使用的版本为:mysql-5.6.24和percona-xtrabackup-2.2.12
本来想使用二进制xtrabackup来备份的,发现这个工具很多功能不完备,主要是不备份表结构(*.frm)。最终还是使用perl脚本工具innobackupex,它对xtrabackup进行了完善,所以需要将xtrabackup加到搜索路径里:
export PATH=$PATH:`pwd`/bin
需要安装perl的mysql接口:
sudo apt-get install libdbd-mysql-perl # perl连接mysql的依赖库,mysql数据备份工具innobackupex需要
mkdir BACKUP
./innobackupex --defaults-file=`pwd`/conf/my.cnf --user=xxx --password=xxx ./BACKUP
尽管可以使用-sock或者-host来备份,但是有很多参数需要设置,还是使用--defaults-file最方便。上面的命令是一个全量备份。
./innobackupex --defaults-file=`pwd`/conf/my.cnf --user=xxx --password=xxx --incremental ./BACKUP --incremental-basedir=./BACKUP/2015-09-15_01-03-11/
./innobackupex --defaults-file=`pwd`/conf/my.cnf --user=xxx --password=xxx --incremental ./BACKUP --incremental-basedir=./BACKUP/2015-09-15_01-10-09/
--incremental指明了增量文件的存储位置,--incremental-basedir是增量的基准数据。
./innobackupex --apply-log --redo-only BACKUP/2015-09-15_01-03-11/
./innobackupex --apply-log --redo-only BACKUP/2015-09-15_01-03-11/ --incremental-dir `pwd`/BACKUP/2015-09-15_01-10-09
./innobackupex --apply-log BACKUP/2015-09-15_01-03-11/ --incremental-dir `pwd`/BACKUP/2015-09-15_01-12-29/
./innobackupex --apply-log BACKUP/2015-09-15_01-03-11/
从基准的全量数据依次进行恢复,直到把所有增量数据应用上去。前面的操作使用--redo-only是表示不进行会话回滚,只有最后一次添加增量数据时才不需要--redo-only。执行完上面的操作,生成的数据就可以使用了,停掉mysql,将数据拷贝到目标位置就OK了。
注意执行命令的输出,可以知道当前处理到的LSN,以及binlog的位置值:
>> log scanned up to (1743414)
xtrabackup: The latest check point (for incremental): '1743414'
xtrabackup: Stopping log copying thread.
.>> log scanned up to (1743414)
...
innobackupex: MySQL binlog position: filename 'binlog.000047', position 120
使用恢复好的数据:
cp -r BACKUP/2015-09-15_01-03-11/ ./dest/data
备份跟全量数据一样,只是需要加上一些参数来指定备份的库或者表,方式很多:
innobackupex --include=’^mydatabase[.]mytable’ /path/to/backup
echo "mydatabase.mytable" > /tmp/tables.txt
innobackupex --tables-file=/tmp/tables.txt /path/to/backup
innobackupex --databases="mydatabase.mytable mysql" /path/to/backup
上面的例子是备份mydatabase.mytable表和mysql库。
局部数据恢复步骤很多,也比较麻烦。例如先创建了如下一些备份,一次全量,两次增量:
./innobackupex --defaults-file=`pwd`/conf/my.cnf --user=xxx --password=xxx ./BACKUP/ --databases='test'
./innobackupex --defaults-file=`pwd`/conf/my.cnf --user=xxx --password=xxx --incremental ./BACKUP/ --databases='test' --incremental-dir=`pwd`/BACKUP/2015-09-15_15-39-46
./innobackupex --defaults-file=`pwd`/conf/my.cnf --user=xxx --password=xxx --incremental ./BACKUP/ --databases='test' --incremental-dir=`pwd`/BACKUP/2015-09-15_15-44-01
恢复数据,跟全部数据的操作一样:
./innobackupex --apply-log --redo-only BACKUP/2015-09-15_15-39-46/
./innobackupex --apply-log --redo-only BACKUP/2015-09-15_15-39-46/ --incremental-dir=`pwd`/BACKUP/2015-09-15_15-44-01/
./innobackupex --apply-log BACKUP/2015-09-15_15-39-46/ --incremental-dir=`pwd`/BACKUP/2015-09-15_15-44-41/
./innobackupex --apply-log BACKUP/2015-09-15_15-39-46/
innodb直接拷贝.frm和.ibd文件是不能直接使用的,因为会有tablespace id等其他信息存储在ibdata1文件中,直接拷贝会出现表找不到的问题。所以从.frm和.ibd文件恢复表结构和表数据会很麻烦,这里先借助mysql-utilities-1.5.5里的mysqlfrm.py工具来来读取二进制.frm文件,来获取表结构,这个工具是一个python库:
python scripts/mysqlfrm.py --diagnostic ../BACKUP/2015-09-15_15-39-46/test/*.frm
注意:这个工具并不怎么靠谱,所以应经常使用mysqldump --no-data dbname进行表结构备份。将输出的sql语句在mysql中执行,以创建需要的表,然后在mysql中删除新表自带的.ibd:
alter table student discard tablespace;
alter table teacher discard tablespace;
然后再将我们恢复的.ibd文件拷贝回去:
cp -r BACKUP/2015-09-15_10-08-47/test/*.frm data/test/
接着再使用import命令导入我们刚才拷贝过去的数据,局部恢复的整个过程都不需要停mysql服务:
alter table teacher import tablespace;
alter table student import tablespace;
innobackupex --stream=tar ./ | gzip - > backup.tar.gz
innobackupex --stream=tar ./ | bzip2 - > backup.tar.bz2
innobackupex --stream=tar ./ | ssh user@destination \ "cat - > /data/backups/backup.tar"
解压时需要使用-i参数,如下:
tar -xizf backup.tar.gz
直接网络端口传输:
## On the destination host:
$ nc -l 9999 | cat - > /data/backups/backup.tar
## On the source host:
$ innobackupex --stream=tar ./ | nc desthost 9999
压缩备份的增量压缩处理需要使用--incremental-lsn=LSN-number,也就是需要记住上次处理到的lsn值,而且打包方式好像不支持tar,只支持xbstream。