xtrabackup备份还原
公司业务对事务性要求越来越高,再者mysqldump备份锁表情况严重,又赶上服务器更新换代,硬件需求得到能充分满足,因此,决定开始myisam转为innodb,我呢作为排头兵,被安排测试xtrabackup备份还原数据库。下面我把自己测试xtrabackup备份mysql库的过程做个小结;
测试环境
操作系统:redhat 5.6
mysql版本:mysql 5.1.38
port:3333
库名:wyett
xtrabackup:下载地址:http://www.percona.com/downloads/XtraBackup/
选择2.0.8这个版本,不选2.1以后版本是因为2.1以后版本不支持mysql 5.1的备份;2.0以前版本bug有个碗口大的伤疤啊,对于表文件大于8G的表,在还原时会报错;这两个问题也是笔者在巧合下发现的,特别2.0版本,实在是很受折磨,可能有不缺之处,希望大家见谅!
安装xtrabackup
直接下载xtrabackup的rpm安装包安装;
1 # sudo rpm -ivh percona-xtrabackup-20-2.0.8-587.rhel5.x86_64.rpm --nodeps 2 # sudo ln –s /usr/local/mysql/bin/mysql /usr/bin/mysql 3 # export PATH=$PATH:/usr/local/mysql/bin
第1行加nodeps参数,否则:
1 # sudo rpm -ivh percona-xtrabackup-20-2.0.8-587.rhel5.x86_64.rpm 2 warning: percona-xtrabackup-20-2.0.8-587.rhel5.x86_64.rpm: Header V4 DSA signature: NOKEY, key ID cd2efd2a 3 error: Failed dependencies: 4 /usr/bin/mysql is needed by percona-xtrabackup-20-2.0.8-587.rhel5.x86_64
第2行创建一个软链,因为是从官网下载的rpm包,需要一个/usr/bin/mysql下的环境依赖,也可以自己做一个适合的rpm包
第3行设置环境变量
端口备份还原
1、备份
1 sudo /usr/bin/innobackupex-1.5.1 \ 2 --defaults-file=/mysqldata/mysql/data/mysql3333/my3333_master.cnf \ 3 --user=root --host=127.0.0.1 --port=3333 --stream=tar --slave-info \ 4 /mysqlbak/boze/ \ 5 2>/mysqlbak/boze/1.log | gzip -c9 >/mysqlbak/boze/3333_bak.tar.gz
打开1.log文件看一看,以下面类似结尾,并且通篇没有error字样,备份成功:
1 innobackupex-1.5.1: Backup created in directory '/mysqlbak/boze' 2 innobackupex-1.5.1: MySQL binlog position: filename 'mysql3333.000001', position 106 3 innobackupex-1.5.1: MySQL slave binlog position: master host '', filename '', position 4 innobackupex-1.5.1: You must use -i (--ignore-zeros) option for extraction of the tar stream. 5 140114 17:13:29 innobackupex-1.5.1: completed OK!
2、copy备份到新服务器并解压,创建新文件夹/mysqlbak/boze/db
1 # cd /mysqlbak/boze 2 # mkdir ./db 3 # tar –izxvf 3333_bak.tar.gz –C ./db/
看一看./db/中的文件,与原库相比较,权限发生了变化,暂时先不管;
# ll total 10288 -rw-r--r-- 1 root root 268 Jan 14 17:13 backup-my.cnf -rw-rw---- 1 root root 10485760 Jan 14 15:51 ibdata1 drwxr-xr-x 2 root root 4096 Jan 14 17:26 mysql drwxr-xr-x 2 root root 4096 Jan 14 17:26 wyett -rw-r--r-- 1 root root 10 Jan 14 17:13 xtrabackup_binary -rw-r--r-- 1 root root 23 Jan 14 17:13 xtrabackup_binlog_info -rw-rw---- 1 root root 73 Jan 14 17:13 xtrabackup_checkpoints -rw-rw---- 1 root root 2560 Jan 14 17:13 xtrabackup_logfile -rw-r--r-- 1 root root 53 Jan 14 17:13 xtrabackup_slave_info
3、处理新服务器端口:
Copy出端口配置文件,端口号可以不同,停止新端口服务,删除新端口数据文件
1 # sudo cp /mysqldata/mysql/data/mysql3333/my3333_master.cnf /mysqlbak/boze/ 2 # sudo /etc/init.d/mysql3333 stop 3 # cd /mysqldata/mysql/data/mysql3333/ 4 # sudo rm –rf ./*
4、还原;
应用日志
1 # sudo /usr/bin/innobackupex-1.5.1 --user=root \ 2 # --host=127.0.0.1 --port=3333 \ 3 # --defaults-file=/mysqlbak/boze/my3333_master.cnf \ 4 # --apply-log /mysqlbak/boze/db/
执行结果:
xtrabackup: starting shutdown with innodb_fast_shutdown = 1 140114 17:34:59 InnoDB: Starting shutdown... 140114 17:34:59 InnoDB: Shutdown completed; log sequence number 45580 140114 17:34:59 innobackupex-1.5.1: completed OK!
copy备份
1 # sudo /usr/bin/innobackupex-1.5.1 --user=root \ 2 # --host=127.0.0.1 --port=3333 \ 3 # --defaults-file=/mysqlbak/boze/my3333_master.cnf \ 4 # --copy-back /mysqlbak/boze/db/
执行结果如下,可以看到这一步实际就是copy过程,当时测试出2.0版本8G这个BUG就是在这一步发现的:
innobackupex-1.5.1: Finished copying back files. 140114 17:41:27 innobackupex-1.5.1: completed OK!
5、修改所有库文件夹的权限和所有者
1 # cd /mysqldata/mysql/data/mysql3333/ 2 # sudo chown –R mysql.mysql ./ 3 # sudo ls -l | grep ^d | awk -F " " '{print $9}' | xargs sudo chmod -R 660 4 # sudo ls -l | grep ^d | awk -F " " '{print $9}' | xargs sudo chmod 700
把my3333_master.cnf复制到对应目录中:
# ll total 797500 -rw-r--r-- 1 mysql mysql 10485760 Jan 14 17:37 ibdata1 -rw-r--r-- 1 mysql mysql 268435456 Jan 14 17:38 ib_logfile0 -rw-r--r-- 1 mysql mysql 268435456 Jan 14 17:41 ib_logfile1 -rw-r--r-- 1 mysql mysql 268435456 Jan 14 17:39 ib_logfile2 -rw-r--r-- 1 root root 20399 Jan 14 17:46 my3333_master.cnf drwx------ 2 mysql mysql 4096 Jan 14 17:37 mysql drwx------ 2 mysql mysql 4096 Jan 14 17:37 wyett -rw-r--r-- 1 mysql mysql 53 Jan 14 17:37 xtrabackup_slave_info
注:test库哪里去了?
6、启动端口,搭建从库;
注:数据文件中会有以下两个文件:
如果想做备份机的从库,使用xtrabackup_binlog_info的pos
如果想做备份机的主库的从库,使用xtrabackup_slave_info的pos
后面内容比较简略,只列出相关脚本,步骤都是一样的。
单库备份还原
1、备份,加一个参数--database
1 # sudo /usr/bin/innobackupex-1.5.1 \ 2 --defaults-file=/mysqldata/mysql/data/mysql3333/my3333_master.cnf \ 3 --database=wyett \ 4 --user=root --host=127.0.0.1 --port=3333 --stream=tar --slave-info \ 5 /mysqlbak/boze/ \ 6 2>/mysqlbak/boze/1.log | gzip -c9 >/mysqlbak/boze/wyett.tar.gz
2、copy解压,创建目录/mysqlbak/boze/db1/
[dbauser5@jyw-dm-yhzx01 db1]$ ll total 10284 -rw-r--r-- 1 root root 268 Jan 14 17:59 backup-my.cnf -rw-rw---- 1 root root 10485760 Jan 14 15:51 ibdata1 drwxr-xr-x 2 root root 4096 Jan 14 18:05 wyett -rw-r--r-- 1 root root 10 Jan 14 18:00 xtrabackup_binary -rw-r--r-- 1 root root 23 Jan 14 18:00 xtrabackup_binlog_info -rw-rw---- 1 root root 73 Jan 14 18:00 xtrabackup_checkpoints -rw-rw---- 1 root root 2560 Jan 14 18:00 xtrabackup_logfile -rw-r--r-- 1 root root 53 Jan 14 18:00 xtrabackup_slave_info
3、还原单库,同样要求停止端口,清空datadir目录,脚本不变,也就是说,尽管是单库备份,你需要为它单起一个端口,在已有文件或者库的端口里是没办法恢复xtrabackup库的。笔者对这点一直有怀疑,只是可惜没有进展:
sudo /usr/bin/innobackupex-1.5.1 --user=root \ --host=127.0.0.1 --port=3333 \ --defaults-file=/mysqlbak/boze/my3333_master.cnf \ --apply-log /mysqlbak/boze/db1/
增量备份还原
1、完整备份:
1 sudo /usr/bin/innobackupex-1.5.1 \ 2 --defaults-file=/mysqldata/mysql/data/mysql3333/my3333_master.cnf \ 3 --user=root --host=127.0.0.1 --port=3333 --stream=tar --slave-info \ 4 /mysqlbak/boze/db2/ >/mysqlbak/boze/1.log
备份结果:
1 $ ll 2 total 4 3 drwxr-xr-x 4 root root 4096 Feb 17 14:28 2014-02-17_14-28-04
2、增量备份:
1 sudo /usr/bin/innobackupex-1.5.1 \ 2 --defaults-file=/mysqldata/mysql/data/mysql3333/my3333_master.cnf \ 3 --user=root --host=127.0.0.1 --port=3333 --slave-info \ 4 --incremental --incremental-basedir=/mysqlbak/boze/db2/2014-02-17_14-28-04/ \ 5 /mysqlbak/boze/db2/ >/mysqlbak/boze/1.log
--incremental指明是增量备份
--incremental-basedir指定上次完整备份或者增量备份文件的位置。
增量备份结果:
1 drwxr-xr-x 4 root root 4096 Feb 17 14:28 2014-02-17_14-28-04 2 drwxr-xr-x 4 root root 4096 Feb 17 14:33 2014-02-17_14-33-33
3、还原:
apply_log全备:
1 sudo /usr/bin/innobackupex-1.5.1 --user=root \ 2 --host=127.0.0.1 --port=3333 \ 3 --defaults-file=/mysqlbak/boze/my3333_master.cnf \ 4 --apply-log /mysqlbak/boze/db2/2014-02-17_14-28-04/
apply_log增量备份到全备:
1 sudo /usr/bin/innobackupex-1.5.1 --user=root \ 2 --host=127.0.0.1 --port=3333 \ 3 --defaults-file=/mysqlbak/boze/my3333_master.cnf \ 4 --apply-log /mysqlbak/boze/db2/2014-02-17_14-28-04/ \ 5 --incremental-dir=/mysqlbak/boze/db2/2014-02-17_14-33-33/
然后copy回datadir下,修改权限,启动端口即可;
xtrabackup备份原理
完整备份的原理:
对于InnoDB,XtraBackup基于InnoDB的crash-recovery功能进行备份。
crash-recovery是这样的:InnoDB维护了一个redo log,又称为 transaction log,也叫事务日志,它包含了InnoDB数据的所有改动情况。InnoDB启动的时候先去检查datafile和transaction log,然后应用所有已提交的事务并回滚所有未提交的事务。
XtraBackup在备份的时候并不锁定表,而是一页一页地复制InnoDB的数据,与此同时,XtraBackup还有另外一个线程监视着transactions log,一旦log发生变化,就把变化过的log pages复制走(因为transactions log文件大小有限,写满之后,就会从头再开始写,新数据可能会覆盖到旧的数据,所以一旦变化就要立刻复制走)。在全部数据文件复制完成之后,停止复制logfile。
XtraBackup采用了其内置的InnoDB库以read-write模式打开InnoDB的数据文件,然后每次读写1MB(1MB/16KB=64page)的数据,一页一页地遍历,同时用InnoDB的buf_page_is_corrupted()函数检查此页的数据是否正常,如果正常则进行复制,如不正常则重新读取,最多重读10次,如果还是失败,则备份失败退出。复制transactions log的原理也是一样的,只不过每次读写512KB(512KB/16KB=32page)的数据。
由于XtraBackup其内置的InnoDB库打开文件的时候是rw的,所以运行XtraBackup的用户,必须对InnoDB的数据文件具有读写权限。
由于XtraBackup要从文件系统中复制大量的数据,所以它尽可能地使用posix_fadvise(),来告诉OS不要缓存读取到的数据(因为这些数据不会重用到了),从而提升性能。如果要缓存的话,大量的数据会对OS的虚拟内存造成很大的压力,其它进程(如mysqld)很有可能会被swap出去,这样就出问题了。同时,XtraBackup在读取数据的时候还尽可能地预读。
由于不锁表,所以复制出来的数据是不一致的,数据的一致性是在恢复的时候使用crash-recovery进行实现的。
对于MyISAM,XtraBackup还是首先锁定所有的表,然后复制所有文件。
增量备份的原理:
在完整备份和增量备份文件中都有一个文件xtrabackup_checkpoints会记录备份完成时检查点的LSN。在进行新的增量备份时,XtraBackup会比较表空间中每页的LSN是否大于上次备份完成的LSN,如果是,则备份该页,并记录当前检查点的LSN。
原理部分摘自:http://blog.csdn.net/yongsheng0550/article/details/6682162
更多内容请参考:http://www.mike.org.cn/articles/xtrabackup-guide/