xtrabackup备份原理及流式备份应⽤
⽬录
xtrabackup备份原理及流式备份应⽤
0. 参考⽂献
序号⽂献
1
2
3
4
5
6
7
xtrabackup 是⼀款开源的MySQL备份解决⼯具,由percona公司开发完成。相⽐于MySQL企业版的mysqlbackup 和ibbackup功能强⼤许多。尤其提供了当前部门需求的流式备份功能,因此在⽬前看来xtrabackup是⼀款⾮常合适的MySQL备份⼯具。本⽂将从xtrabackup备份的应⽤与原理⾓度介绍xtrabackup。
1. xtrabackup 安装
1. 8.0 : MySQL 8.0 以上版本
2. 2.4 : MySQL 5.7 版本
3. 2.2 和 2.3 : MySQL 5.1, 5.5 和 5.6
当前线上使⽤的MySQL版本是5.7版本,因此本⽂所有的内容都是基于2.4版本⽣成的。如果读者对于8.0 有兴趣,可以阅读其⽂档:
下载下来的⽂件中,bin⽬录下会有如下的⼏个⽂件:
mysql连接工具~/percona-xtrabackup-2.4.15-Linux-x86_64/bin$ ls -la
total 211188
drwxr-xr-x 2 mysql mysql      4096 Oct 12 13:20 .
drwxr-xr-x 6 mysql mysql      4096 Jul  5 16:00 ..
lrwxrwxrwx 1 mysql mysql        10 Jul  5 16:00 innobackupex -> xtrabackup
-rwxr-xr-x 1 mysql mysql  9811072 Jul  5 15:53 xbcloud
-rwxr-xr-x 1 mysql mysql      3020 Jul  5 15:52 xbcloud_osenv
-rwxr-xr-x 1 mysql mysql  5854168 Jul  5 15:53 xbcrypt
-rwxr-xr-x 1 mysql mysql  5942024 Jul  5 15:53 xbstream
-rwxr-xr-x 1 mysql mysql 194628336 Jul  5 15:59 xtrabackup
1. xbcloud, xbcloud_osenv : 是xtrabackup新的⾼级特性云备份
2. xbcrypt : ⽀持加密备份
3. xbstream : ⽀持流式备份功能。可以将备份的内容打包并通过管道传递
4. xtrabackup : 是备份功能的主程序
5. innobackupex : 这个⼯具在之前的版本中是⼀个perl脚本,会调⽤xtrabackup这个⼆进制⼯具。从xtrabackup 2.3开始,该⼯具使
⽤C语⾔进⾏了重写,当前它是xtabackup⼆进制⼯具的⼀个软连接,但是实际的使⽤⽅法却不同,并且在以后的版本中会删除该⼯具。
因为innobackupex在后续版本中已经不存在。因此本⽂将会主要介绍xtrabackup的备份恢复⽅法和原理。
2. xtrabackup 备份和恢复原理
对于xtrabackup备份和恢复数据的过程总体分为3个阶段:
1. 备份(backup)
2. 准备(prepare)
3. 恢复(copy-back 或move-back)
2.1 备份阶段(backup)
对于MySQL的备份,在⼤部分的情况下需要完成以下两种类型的数据的备份:
1. innodb 存储引擎数据的备份。
2. ⾮事务引擎的数据备份,例如myisam 引擎数据的备份。
在备份的过程中 基本处于可读写的状态,因此在这期间需要对于变化的数据进⾏处理,以便在备份结束时获取正确的备份数据。基于上述的考虑xtrabackup备份的过程主要包括了以下的⼏个步骤:
拷贝和监控redo log : 在起始时刻,xtrabackup会先获取MySQL当前时刻的LSN,同时开始拷贝redo log⾄xtrabackup_logfile⽂件中。因为在备份的过程中数据库基本处于可读写的状态下,因此redo log会不断的变化,将导致初始拷贝的redo log和MySQL当前的redo log不⼀致。所以在xtrabackup后台,还会启动另外的⼀个进程持续监控redo log⽂件的变化。如果监控到⽂件发⽣变化,则将其写⼊到xtrabackup_logfile中。这个进程会⼀直存在并执⾏监控redo log的变化,直到备份将结束为⽌。
拷贝innodb相关⽂件:拷贝包括ibdata1(共享表空间)和*.idb(如果开启了独⽴表空间的话)相关的⽂件。
加备份锁:因为⾮innodb表没有redo log可供拷贝,所以在备份⾮innodb表之前需要对数据库加锁,以防⽌在备份过程中数据被修改。在这⾥需要先简单的介绍下备份锁的概念。在各种备份⼯具备份数据库的过程中,为了获取⼀致性备份(binlog位置与数据匹配),需要在备份的过程中加上备份锁。在MySQL中会使⽤FLUSH TABLES WITH READ LOCK简称(FTWRL)来获取⼀致性备份。
FTWRL会执⾏如下的⼏个操作(更具体的介绍和相关原理可以参见):
1. 上全局读锁(lock_global_read_lock):阻塞所有的更新操作。
2. 清理表缓存(close_cached_tables):关闭表缓存。
3. 上全局COMMIT锁(make_global_read_lock_block_commit):阻塞活跃的事务提交。
FTWRL的操作中会阻塞包括innodb在内的所有存储引擎的更新操作。在FTWRL执⾏的过程中,整个数据库相当于只读模式。可见如果在线上数据库中(尤其在承担线上读写业务的数据库下),使⽤FTWRL可能会导致线上数据库长时间陷⼊不可写⼊的状态。对于这个问题percona版本的MySQL做出了优化,将FTWRL 分为了⼏个部分:
1. lock table for backup : 这个锁会阻塞所有对⾮事务表的更新及所有DDL动作,但是innodb表的读写可以继续执⾏。
2. lock binlog for backup:做锁会阻⽌binlog更新,因此此时所有的DML操作都会被阻塞。
可以看出如果在备份的过程中,将FTWRL拆解成如上的2步操作,则在备份⾮事务表的过程中可以不阻塞事务表的更新。对于xtrabackup 如果备份的数据库是不⽀持backup lock的版本,则使⽤FTWRL操作。⽽如果是⽀持backup lock的版本,则使⽤lock tables for
backup获取轻量级的backup locks来替代FTWRL。
拷贝⾮innodb表⽂件。
获取binlog⼀致性位置:在拷贝完所有的数据之后,备份进⼊收尾阶段。在这⾥根据是否⽀持backup lock分为不同的操作。对于不⽀持backup lock的版本,直接获取binlog的⼀致性坐标点同时结束redo log的监控和拷贝并释放锁。⽽对于⽀持backup lock的版本,先通过lock binlog for bakcup来获取binlog⽇志锁,然后结束redo log的监控和拷贝,再unlock tables释放表锁,随后获取⼆进制⽇志的⼀致性位置坐标点,最后unlock binlog释放binlog⽇志锁。
结束备份退出。
2.2 准备阶段(prepare)
在恢复备份之前需要对数据进⾏⼀些处理,在xtrabackup中称之prepare。这个步骤的主要⼯作就是将之前记录的redo log应⽤到innodb 的数据中,使得innodb中的数据最终和备份结束的时刻⼀致。这个步骤不需要在有MySQL的机器上运⾏,xtrabackup⾃⾝实现了⼀个简化版本的innodb引擎,通过它完成redo log的应⽤。
2.3 恢复(copy-back 或move-back)
在最后⼀步,xtrabackup会将数据copy 或者move (如果DBA不打算保留备份数据)到数据库对应的⽬录下。同样这步也不需要MySQL启动或者存在,可以在任何机器上执⾏。但是要求对应的数据库⽬录下是空的,不存在任何的⽂件。
最后根据如上的叙述可以归纳总结如下:
3. xtrabackup 流式备份应⽤
当前对于部门的MySQL集存在如下的痛点:
1. 备份磁盘空间不⾜:随着线上数据的增长,⼤部分MySQL数据库都没有预留⾜够的备份空间,因此当前每次在本地备份数据都会导致
磁盘空间报警。在DBA处理不及时的情况下,容易导致磁盘空间占满⽽影响服务。
⽽xtrabackup正好有流式备份的功能,能够解决当前DBA的痛点。因此本⼩节将主要介绍下xtrabackup的流式备份功能(stream模式)。当前 xtrabackup⽀持2种⽅式的流式备份:
1. tar格式(ps : tar 和ssh还有很多有意思的功能,具体可以参考 )
2. xbstream格式
在测试xtrabackup备份功能之前需要先准备下实验环境。
机器IP CPU磁盘内存
机器1192.168.100.140核  1.1T SSD(已使⽤60%)64G
机器2192.168.100.240核  1.1T SSD(空盘)64G
需要完成的操作是从机器1备份数据到机器2,并且不占⽤机器1原本不多的剩余磁盘空间。为了能够使⽤流式备份功能,⾸先需要在机器2上完成如下2个步骤:
1. 配置从机器1免密ssh登录机器2。
2. 在机器2上建⽴存放备份的⽬录,本例中路径为/ssd/100_1_bak/
tar格式的备份可以选择使⽤gzip或者不压缩。在本例中分别使⽤如下命令完成:
xtrabackup --safe-slave-backup --slave_info --user='root' --password='XXXXXX'  --backup  --tables-file=./tb.txt  --stream=tar  | ssh  root@192.168.100.2  " xtrabackup --safe-slave-backup --slave_info --user='root' --password='XXXXXX'  --backup  --tables-file=./tb.txt  --stream=tar  |pigz | ssh -p32200 mysql@192.168
ps : xtrabackup没有选项只备份innodb表或者myisam表。但是可以通过选项指定备份的表。在本例中通过--tables-file选项,将需要备
份的innodb表写⼊tb.txt⽂件中进⾏备份。⽣成tb.txt的内容可以使⽤如下的sql语句获得:
select CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)  FROM information_schema.TABLES  WHERE  ENGINE = 'InnoDB'    AND ENGINE IS NOT NUL
如果使⽤xbstream格式,则可以使⽤如下的命令:
xtrabackup --safe-slave-backup --slave_info --user='root' --password='XXXXXX'  --backup  --tables-file=./tb.txt  --stream=xbstream  | ssh -p32200 mysql@ xtrabackup --safe-slave-backup --slave_info --user='root' --password='XXXXXX'  --backup  --tables-file=./tb.txt  --stream=xbstream  --compress  | s
sh -p32200 m
4. 总结
本⽂主要介绍了xtrabackup备份的原理以及流式备份功能。限于本⽂的作者⽔平有限,⽂中的错误在所难免,恳请⼤家批评指正。