青蛙学Linux—MySQL备份工具XtraBackup
XtraBackup是Percona公司开发的一款免费开源的MySQL备份工具。与上一篇介绍的mysqldump不同,XtraBackup可以对MySQL进行物理备份(备份的是MySQL的文件而不是生成sql文件),且XtraBackup可以对MySQL进行在线备份。
1、安装XtraBackup
要安装XtraBackup,可以在Percona公司的官网上下载CentOS的RPM安装包,也可以使用Percona提供的YUM源。这里介绍通过YUM进行安装的方法。
首先在https://www.percona.com/downloads/percona-release/redhat/上下载Percona提供的YUM的RPM包,然后安装该RPM包即可使用Percona的YUM源,通过该YUM源可以安装所有的Percona产品。
通过以下命令查看可以安装的XtraBackup版本:
[root@localhost ~]# yum list percona-xtrabackup*
这里选择2.4的版本进行安装:
[root@localhost ~]# yum install percona-xtrabackup-24.x86_64
2、XtraBackup主要工具
使用XtraBackup进行备份时,主要使用以下两个工具:
- xtrabackup
- innobackupex
xtrabackup工具只能备份InnoDB和XtraDB两种引擎的数据库,而且只备份idb文件不备份frm文件;同时,xtrabackup不能备份表结构和触发器等。
innobackupex是使用Perl脚本对xtrabackup进行的封装和功能扩展。innobackupex可以备份和恢复MyISAM、InnoDB和XtraDB引擎的表和frm文件,所以通常使用innobackupex来备份MySQL。
这两个工具都是根据MySQL配置文件my.cnf来获取备份文件的,同时需要连接到数据库和数据存储目录的操作权限。
注意:innobackupex在备份使用MyISAM的数据库时,会对全库进行加锁操作,阻塞写操作,若备份是在从库上进行的话会影响主从复制,产生延迟。而对于使用InnoDB的数据库,则不会阻塞读写。
3、XtraBackup备份恢复过程
3.1、MyISAM引擎
XtraBackup首先执行flush tables with read lock生成锁以阻止新的写入,然后将表中的数据刷新使其全部保存到硬盘上,接着开始复制文件,文件复制完成后释放锁。
3.2、InnoDB引擎
备份
XtraBackup在开始备份时会记住log sequence number(LSN),然后开始复制文件。同时,XtraBackup会启动一个后台进程用于监视事务日志,并从事务日志中复制最新的修改,该操作是持续进行的。所以XtraBackup在备份InnoDB时不会产生阻塞。
恢复—准备(prepare)阶段
XtraBackup使用事务日志对备份的数据进行前滚和回滚操作,以保证这些数据与备份结束时的数据库状态一致。
恢复—恢复阶段
XtraBackup在准备阶段完成后,即可使用准备好的数据对InnoDB进行恢复。
4、使用XtraBackup
4.1、innobackupex语法及常用选项
innobackupex的命令语法如下:
innobackupex --选项
常用选线:
- --host:指定连接的MySQL主机
- --port:指定连接的MySQL端口
- --socket:指定连接本地数据库时使用的MySQL socket路径
- --user:备份使用的MySQL用户
- --password:备份使用的MySQL用户的密码
- --databases:对指定的数据库进行备份,指定多个库时使用”库1 库2 … 库n”表示
- --no-timestamp:不使用以时间命名的目录保存备份数据,使用名为BACKUP-DIR的目录保存备份数据
- --default-files:指定MySQL配置文件的路径,该选项必须在所有选项之前;XtraBackup默认使用/etc/my.cnf这个配置文件
- --incremental:创建增量备份
- --incremental-basedir:指定基于哪个备份做增量备份
- --incremental-dir:在恢复阶段的准备过程中用于指定增量备份的路径
- --apply-log:应用xtrabackup_logfile文件,重做已提交的事务,回滚未提交的事务
- --redo-only:只重做已提交的事务,不回滚未提交的事务
- --use-memory:在恢复过程中的准备阶段可以使用的内存大小
- --copy-back:恢复备份到数据库的数据存储目录
- --compact:压缩备份
- --stream={tar|xbstream}:在备份过程中对数据进行流式化处理,不经过中间阶段直接压缩
- --parallel:指定启动的线程数,用于提高备份速度
在使用XtraBackup进行备份时,建议创建一个仅用于执行备份的MySQL用户,只授予以下权限:
reload,lock tables,replication client,create tablespace,super,process
4.2、使用innobackupex进行完全备份
这里使用一个例子来演示如何使用innobackupex对MySQL进行完全备份。
实验环境:
- MySQL通过源码安装,配置文件未/etc/my.cnf,socket文件为/tmp/mysqld.sock
- 使用MySQL的backup用户进行备份,用户密码为123456
- 备份数据存储在目录/data/backup/full目录下
运行以下命令进行备份:
[root@localhost full]# innobackupex --user=backup --password=123456 --socket=/tmp/mysqld.sock /data/backup/full
innobackupex会在指定的备份目录下产生一个以时间戳命名的目录并将备份的数据存储在该目录中。在该目录中除了备份的MySQL数据库文件,还有以下几个文件:
backup-my.cnf # 备份用到的配置选项信息 xtrabackup_checkpoints # 记录备份的类型、起始LSN和结束LSN等信息 xtrabackup_info # 记录备份过程中的各种详细信息 xtrabackup_logfile # 事务日志文件,用于在恢复过程中的准备阶段对备份的数据进行前滚和回滚操作
4.3、使用完全备份进行恢复
这里通过将上面备份的数据进行恢复来介绍如何进行完全备份的恢复。
准备阶段(prepare)
该阶段仅对使用InnoDB引擎的MySQL有意义。在该阶段中将调用xtrabackup_logfile对备份的数据进行前滚和回滚操作。使用以下命令执行prepare:
[root@localhost full]# innobackupex --apply-log /data/backup/full/2019-01-29_15-22-00
恢复数据库
在prepare阶段执行成功后,就可以恢复数据库了。使用以下命令进行数据库恢复:
[root@localhost full]# innobackupex --default-file=/etc/my.cnf --copy-back /data/backup/full/2019-01-29_15-22-00
注意以下两点:
- 进行恢复时必须先关闭MySQL服务
- MySQL的数据存储目录必须为空,因为innobackupex不会覆盖已经存在的文件
修改数据存储目录的权限
恢复完成后,必须修改重新生成的数据存储目录的权限为运行MySQL的用户,否则MySQL将无法读取该目录:
[root@localhost db]# chown -R mysql:mysql mysql
完成以上步骤后,启动MySQL即可。
4.4、使用innobackup进行增量备份
第一次的增量备份必须基于一个完全备份,之后每次的增量备份都是基于上一次的增量备份进行的。
注意:增量备份主要针对InnoDB,对于MyISAM而言,仍然是完全备份。
这里通过上面的完全备份进行两次增量备份来演示如何进行增量备份。
第一次增量备份(基于完全备份):
[root@localhost incremental]# innobackupex --user=backup --password=123456 --socket=/tmp/mysqld.sock --incremental /data/backup/incremental --incremental-basedir=/data/backup/full/2019-01-29_15-22-00
第二次增量备份(基于第一次增量备份):
[root@localhost incremental]# innobackupex --user=backup --password=123456 --socket=/tmp/mysqld.sock --incremental /data/backup/incremental --incremental-basedir=/data/backup/incremental/2019-01-29_15-46-21
4.5、使用增量备份恢复数据库
使用增量备份恢复数据库相对来说步骤比较复杂,在prepare阶段分为以下三个步骤:
- 使用完全备份进行一次prepare操作,此时必须添加—redo-only参数,不回滚未提交的数据,因为这些数据可能在后面的备份中已经提交了
- 将增量备份prepare到完全备份上,除prepare最后一次增量备份外,其他次的增量备份也必须添加—redo-only参数
- 对合并了增量备份的完全备份再进行一次prepare操作,此时生成的数据才可以用于最后的恢复
这里使用上面生成的完全备份和两次增量备份来演示如何使用增量备份进行数据库的恢复:
第一次的prepare(使用完全备份):
[root@localhost backup]# innobackupex --apply-log --redo-only /data/backup/full/2019-01-29_15-22-00
第二次的prepare(使用第一次的增量备份prepare到完全备份上):
[root@localhost backup]# innobackupex --apply-log --redo-only /data/backup/full/2019-01-29_15-22-00 --incremental-dir=/data/backup/incremental/2019-01-29_15-46-21
第三次的prepare(使用第二次的增量备份prepare到完全备份上):
[root@localhost backup]# innobackupex --apply-log /data/backup/full/2019-01-29_15-22-00 --incremental-dir=/data/backup/incremental/2019-01-29_15-50-42
最后一次prepare(使用完全备份最后进行一次完整的prepare):
[root@localhost backup]# innobackupex --apply-log /data/backup/full/2019-01-29_15-22-00
成功执行完以上操作后即可恢复数据库了:
[root@localhost incremental]# innobackupex --default-file=/etc/my.cnf --copy-back /data/backup/full/2019-01-29_16-35-26
4.6、针对海量数据的备份优化
针对海量数据,可以使用XtraBackup提供的流式特性,在备份的过程中直接进行压缩而不经过中间环节。
这里通过一个例子来演示如何使用流式特性:将MySQL中的所有数据库进行完全备份,并将备份直接打包成tar并调用gzip进行压缩,保存在/data/bakcup/tar目录下,运行以下命令
[root@localhost backup]# innobackupex --user=backup --password=123456 --socket=/tmp/mysqld.sock --stream=tar /data/backup/tar |gzip > /data/backup/tar/backup.tar.gz
要对生成的tar.gz包进行解压,需要添加i参数:
[root@localhost tar]# tar -zixvf backup.tar.gz