XtraBackup 简介
1 |
XtraBackup(PXB) 工具是 Percona 公司用 perl 语言开发的一个用于 MySQL 数据库物理热备的备份工具,支持 MySQl(Oracle)、Percona Server 和 MariaDB,并且全部开源,真可谓是业界良心。阿里的 RDS MySQL 物理备份就是基于这个工具做的。由于是采取物理拷贝的方式来做的备份,所以速度非常快,几十G数据几分钟就搞定了,而它巧妙的利用了mysql 特性做到了在线热备份,不用像以前做物理备份那样必须关闭数据库才行,直接在线就能完成整库或者是部分库的全量备份和增量备份。新版本的xtrabackup改成了cmake安装,和以前有点不一样。 |
1 |
版本说明:2.3.3之后不备份死锁,如果数据库是mysql 5.7之后的必须要装2.4.4才可以用,当然了, 会向下兼容的。 |
工具集:软件包安装后,有以下可执行文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
bin/ ├── innobackupex -> xtrabackup #innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表。 ├── xbcloud #把全部或部分xbstream档案从云上下载或上传到云 ├── xbcloud_osenv ├── xbcrypt #加解密备份文件用的 ├── xbstream #类似于tar └── xtrabackup #是用来备份 InnoDB 表的,不能备份非 InnoDB 表 其中最主要的是 innobackupex 和 xtrabackup,前者是一个 perl 脚本,后者是 C/C++ 编译的二进制。Percona 在2.3 版本用C重写了 innobackupex ,innobackupex 功能全部集成到 xtrabackup 里面,只有一个 binary,另外为了使用上的兼容考虑,innobackupex 作为 xtrabackup 的一个软链接。对于二次开发来说,2.3 摆脱了之前2个进程协作的负担,架构上明显要好于之前版本。(Percona XtraBackup 2.3 发布之后,推荐的备份方法是使用 xtrabackup 脚本。 ) xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 mysqld server 没有交互;innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和 mysqld server 发送命令进行交互,如加读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。简单来说,innobackupex 在 xtrabackup 之上做了一层封装。 一般情况下,我们是希望能备份 MyISAM 表的,虽然我们可能自己不用 MyISAM 表,但是 mysql 库下的系统表是 MyISAM 的,因此备份基本都通过 innobackupex 命令进行;另外一个原因是我们可能需要保存位点信息。 另外几个工具相对小众些,xbcrypt 是加解密备份文件用的;xbstream 类似于tar,是 Percona 自己实现的一种支持并发写的流文件格式;两者在备份和解压时都会用到(如果备份用了加密和并发)。xbcloud 工具的作用是:把全部或部分 xbstream 档案从云上下载或上传到云。 |
版本之间的区别:
1 2 3 4 5 6 7 |
8.0是针对mysql 8.0开发的,不兼容5.X的版本 2.4针对5.7开发,兼容5.6,5.5 2.3针对5.6开发,兼容5.5 2.2针对5.5开发 |
2.XtraBackup 安装
yum安装
1.添加源
1 |
yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm |
2.安装
1 |
yum install percona-xtrabackup-24 |
3.安装时缺少依赖包libev.so.4的处理
1 2 |
wget ftp://fr2.rpmfind.net/linux/dag/redhat/el6/en/x86_64/dag/RPMS/libev-4.15-1.el6.rf.x86_64.rpm rpm -ivh libev-4.15-1.el6.rf.x86_64.rpm |
rpm包安装
下载RPM包
1 2 3 4 5 |
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.0/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.0-rc1.1.el7.x86_64.rpm 或者从这里下载 链接:https://pan.baidu.com/s/1q-G39jCS8iQEce5NwKb8UA 提取码:ts34 |
安装
1 |
yum install percona-xtrabackup-24-2.4.0-rc1.1.el7.x86_64.rpm |
移除
1 |
yum remove percona-xtrabackup |
xtrabackup的使用:
1 2 3 4 5 |
xtrabackup包含两个主要的工具,即xtrabackup和innobackupex,二者区别如下: (1)xtrabackup只能备份innodb和xtradb两种引擎的表,而不能备份myisam引擎的表; (2)innobackupex是一个封装了xtrabackup的Perl脚本,支持同时备份innodb和myisam,但在对myisam备份时需要加一个全局的读锁。还有就是myisam不支持增量备份。 |
1.备份过程(全备)
innobackupex 备份过程如下图:

1 2 3 4 |
在图中,备份开始时首先会开启一个后台检测进程,实时检测mysql redo的变化,一旦发现redo中有新的日志写入,立刻将日志记入后台日志文件xtrabackup_log中。 之后复制innodb的数据文件和系统表空间文件ibdata1。 待复制结束后,执行flush tables with read lock操作, 然后复制.frm,MYI,MYD,等文件(执行flush tableswith read lock的目的是为了防止数据表发生DDL操作,并且在这一时刻获得binlog的位置)最后会发出unlock tables,把表设置为可读可写状态,最终停止xtrabackup_log。 |
2.全备恢复
1 |
这一阶段会启动xtrabackup内嵌的innodb实例,回放xtrabackup日志xtrabackup_log,将提交的事务信息变更应用到innodb数据/表空间,同时回滚未提交的事务(这一过程类似innodb的实例恢复)。恢复过程如下图: |

3.增量备份
1 |
innobackupex增量备份过程中的"增量"处理,其实主要是相对innodb而言,对myisam和其他存储引擎而言,它仍然是全拷贝(全备份) |
1 |
"增量"备份的过程主要是通过拷贝innodb中有变更的"页"(这些变更的数据页指的是"页"的LSN大于xtrabackup_checkpoints中给定的LSN)。增量备份是基于全备的,第一次增备的数据必须要基于上一次的全备,之后的每次增备都是基于上一次的增备,最终达到一致性的增备。增量备份的过程如下,和全备的过程很类似,区别仅在第2步。 |

4.增量备份恢复
1 |
和全备恢复类似,也需要两步,一是数据文件的恢复,如图4,这里的数据来源由3部分组成:全备份,增量备份和xtrabackup log。二是对未提交事务的回滚,如图5所示: |


5.innobackupex使用示例
备份前准备:
(全量备份)
1 2 3 4 |
1.创建备份用户 create user 'backup'@'%' identified by '123456'; 2.授权 grant reload,process,lock tables,replication client,create tablespace,super on *.* to 'backup'@'%'; |
进行全备份
备份数据存放在/home/backup_mysql/下面,innobackupex会自动创建一个文件夹,是当前系统的时间戳
1 2 3 4 5 6 7 |
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=123456 --socket=/tmp/mysqld.sock /home/backup_mysql/ 注意:建议不要用sock进行连接,错误较多: 常用命令: innobackupex --defaults-file=/etc/my.cnf --host=192.168.6.121 --user=backup --password=123456 /home/backup_mysql/ 注意:如果你指定了参数--defaults-file,那么此参数就必须位于第一个,否则就会报“--defaults-file must be specified first on the command line” |

备份完成后目录下文件

可以看见有对应数据库的名字 , 比如shooter,还有一个以时间戳命名的目录。我们看看对应文件里面的内容,这几个比较重要 :
1 |
cat xtrabackup_checkpoints |

1 |
cat xtrabackup_binlog_info |

可以看见相关文件记录了LSN,日志偏移量,还可以看见这次是全备份,相信聪明的童鞋们一眼就看懂了
恢复全备
1 |
恢复备份到mysql的数据文件目录,这一过程要先关闭mysql数据库,重命名或者删除原数据文件目录都可以,再创建一个新的数据文件目录,将备份数据复制到新的数据文件目录下,赋权,修改权限,启动数据库 |
1 2 3 4 5 6 7 8 9 10 11 |
/etc/init.d/mysqld stop mv /data/mysql /data/mysql_bak mkdir /data/mysql #对整体的完全备份进行回复,回滚那些未提交的数据 (不添加--redo-only) innobackupex --apply-log /home/backup_mysql/2020-05-21_15-13-09 trabackup: starting shutdown with innodb_fast_shutdown = 1 InnoDB: Starting shutdown... InnoDB: Shutdown completed; log sequence number 5324784140 innobackupex: completed OK! |
恢复数据:
1 2 3 4 5 6 7 8 |
innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /home/backup_mysql/2020-05-21_15-13-09 innobackupex: Starting to copy InnoDB log files innobackupex: in '/data/backup/2014-04-07_23-05-04' innobackupex: back to original InnoDB log directory '/data/mysql' innobackupex: Copying '/data/backup/2014-04-07_23-05-04/ib_logfile1' to '/data/mysql/ib_logfile1' innobackupex: Copying '/data/backup/2014-04-07_23-05-04/ib_logfile0' to '/data/mysql/ib_logfile0' innobackupex: Finished copying back files. 140407 23:27:38 innobackupex: completed OK! |
可以看见已经成功恢复,修改数据目录权限,启动mysql,效验数据是否正常,查看shooter库下面的表中的数据。
1 2 3 4 |
[root@MySQL-01 ~]# chown -R mysql.mysql /data/mysql [root@MySQL-01 ~]# /etc/init.d/mysqld start Starting MySQL................. [ OK ] [root@MySQL-01 ~]# |
增量备份
1 2 3 |
在进行增量备份时,首先要进行一次全量备份,第一次增量备份是基于全备的,之后的增量备份是基于上一次的增量备份,以此类推。 全备份放在/home/backup_mysql/full,增量备份放在/data/backup_mysql/incremental |
先来一次全备份
1 |
innobackupex --defaults-file=/etc/my.cnf --host=192.168.6.121 --user=backup --password=123456 /home/backup_mysql/ |
然后再shooter库的book表插入数据
1 |
insert into book ('15','month'); |
现在来一次增量备份1
1 |
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=123456 --host=192.168.6.121 --incremental /home/backup_mysql/incremental/ --incremental-basedir=/home/backup_mysql/full/2014-04-07_23-37-20/ --parallel=2 |
查看全备与增备文件比较

1 2 3 4 5 |
[root@xjjh-test1 backup_mysql]# du -sh 2020-05-21_15-13-09 1.3G 2020-05-21_15-13-09 [root@xjjh-test1 backup_mysql]# du -sh incremental/2020-05-21_19-12-37 21M incremental/2020-05-21_19-12-37 [root@xjjh-test1 backup_mysql]# |
看见增量备份的数据很小吧,就是备份改变的数据而已。
增量备份恢复
1 2 3 4 5 6 7 8 9 |
增量备份的恢复大体为3个步骤 *恢复完全备份 *恢复增量备份到完全备份(开始恢复的增量备份要添加--redo-only参数,到最后一次增量备份去掉--redo-only参数) *对整体的完全备份进行恢复,回滚那些未提交的数据 恢复完全备份(注意这里一定要加--redo-only参数,该参数的意思是只应用xtrabackup日志中已提交的事务数据,不回滚还未提交的数据) |
1.恢复完全备份
1 |
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --socket=/tmp/mysql.sock --apply-log --redo-only /root/quanbei/back_28-05-2020 |
2. 将增量备份1应用到完全备份
1 2 3 4 |
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --socket=/tmp/mysql.sock --apply-log --redo-only /root/quanbei/back_28-05-2020 --incremental-dir=/root/zengbei/incremental/back_29-05-2020 innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --socket=/tmp/mysql.sock --apply-log --redo-only /root/quanbei/back_28-05-2020 --incremental-dir=/root/zengbei/incremental/back_30-05-2020 innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --socket=/tmp/mysql.sock --apply-log --redo-only /root/quanbei/back_28-05-2020 --incremental-dir=/root/zengbei/incremental/back_31-05-2020 |
3.将增量备份2应用到完全备份(注意恢复最后一个增量备份时需要去掉–redo-only参数,回滚xtrabackup日志中那些还未提交的数据)
1 |
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --socket=/tmp/mysql.sock --apply-log /root/quanbei/back_28-05-2020 --incremental-dir=/root/zengbei/incremental/back_01-06-2020 |
4. 把所有合在一起的完全备份整体进行一次apply操作,回滚未提交的数据:
1 |
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --socket=/tmp/mysql.sock --apply-log /root/quanbei/back_28-05-2020 |
1 |
5. 把恢复完的备份复制到数据库目录文件中,赋权,然后启动mysql数据库,检测数据正确性 , 恢复数据:
1 |
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --socket=/tmp/mysql.sock --copy-back /root/quanbei/back_28-05-2020 |
或者用如下物理方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root@MySQL-01 ~]# /etc/init.d/mysqld stop Shutting down MySQL. [ OK ] [root@MySQL-01 ~]# mv /data/mysql /data/mysql_bak [root@MySQL-01 ~]# mkdir /data/mysql [root@MySQL-01 ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /home/backup_mysql/full/2020-05-21_14-12-37/ innobackupex: Starting to copy InnoDB log files innobackupex: in '/home/backup_mysql/full/2020-05-21_14-12-37/' innobackupex: back to original InnoDB log directory '/data/mysql' innobackupex: Copying '/home/backup_mysql/full/2020-05-21_14-12-37/ib_logfile1' to '/data/mysql/ib_logfile1' innobackupex: Copying '/home/backup_mysql/full/2020-05-21_14-12-37/ib_logfile0' to '/data/mysql/ib_logfile0' innobackupex: Finished copying back files. 140408 00:12:42 innobackupex: completed OK! [root@MySQL-01 ~]# chown -R mysql.mysql /data/mysql [root@MySQL-01 ~]# /etc/init.d/mysqld start Starting MySQL.... [ OK ] [root@MySQL-01 ~]# |
查看数据是否正确
- 本文固定链接: https://www.yoyoask.com/?p=3288
- 转载请注明: shooter 于 SHOOTER 发表