基本原理如下图:
Mysqldump用于备份,不得不提两个关键的参数:
--single-transaction
:在开始备份前,执行start transaction
命令,以此来获取一致性备份,该参数仅对innodb
存储引擎有效。--master-data=2
:主要用于记录一致性备份的位点。理解Mysqldump工作原理
1、调用FTWRL(flush tables with read lock),全局禁止读写
2、开启快照读,获取此时的快照(仅对innodb表起作用)
3、备份非innodb表数据(.frm,.myi,*.myd等)
4、非innodb表备份完毕后,释放FTWRL锁
5 、逐一备份innodb表数据
6、备份完成。
整个过程,可以参考下面一张图,但这张图只考虑innodb表的备份情况,实际上在unlock tables执行完毕之前,非innodb表已经备份完毕,后面的t1,t2和t3实质都是innodb表,而且5.6的mysqldump利用保存点机制,每备份完一个表就将一个表上的MDL锁释放,避免对一张表锁更长的时间。这里可以参考:FLUSH TABLE WITH READ LOCK
说明:
大家可能有一个疑问,为啥备份innodb表之前,就已经将锁释放掉了,这实际上是利用了innodb引擎的MVCC机制,开启快照读后(set transaction isolation level repeatable read
),就能获取那个时间的一致的数据,无论需要备份多长时间,直到整个事务结束(commit
)为止。当然,这个RR级别的快照,对表的元数据也有要求,因为逻辑备份表是一个个进行的,如果在备份某个表之前,这个表做了DDL操作(此时备份事务暂时还没有加MDL
锁),后续再备份这个表时,就会因为表定义不一致而报错(Table definition has changed, please retry transaction
)。所以总地来说,通过保存点机制,可以有效减少DDL
操作的限制,但是也不能完全消除由于DDL操作导致的备份失败问题。
所以基本流程如下:
1、开启redo日志拷贝线程,从最新的检查点开始顺序拷贝redo日志;
2、开启idb文件拷贝线程,拷贝innodb表的数据
3、idb文件拷贝结束,通知调用FTWRL,获取一致性位点
4、备份非innodb表(系统表)和frm文件
5、由于此时没有新事务提交,等待redo日志拷贝完成
6、最新的redo日志拷贝完成后,相当于此时的innodb表和非innodb表数据都是最新的
7、获取binlog位点,此时数据库的状态是一致的。
8、释放锁,备份结束。
完整备份过程如图::
** 说明 :**
我们知道MySQL里面有个double-write
为了防止写的时候页断裂,那么备份读的时候,有没有可能也只一半的page呢?这个其实是有可能的,因此,我们在拷贝page
的时候,需要对page
算checksum
,如果checksum
不符合预期,我们认为拷贝的页面不完整(这种情况可能发生在你在读页面,而后台线程正在刷脏),需要重试。所以,最终也能保证数据的一致性。
”LOCK TABLES FOR BACKUP”
命令来备份非innodb表数据;通过”LOCK BINLOG FOR BACKUP”
来获取一致性位点,尽量减少因为数据库备份带来的服务受损。我们看看采用这两个锁与FTWRL的区别:
UNLOCK TABLES
UNLOCK BINLOG
过程如图:
xtrabackup_checkpoints
中。一般情况下,我们是希望能备份MyISAM表的,虽然我们可能自己不用MyISAM表,但是mysql库下的系统表示MyISAM的,因此备份基本都通过innobackupex命令进行;另外一个原因是我们可能需要保存位点信息。
(1) 备份过程快速、可靠
(2) 备份过程不会打断正在执行的事务
(3) 能够基于压缩等功能节约磁盘空间和流量
(4) 自动实现备份检验
(5) 还原速度快
官网yum源安装方法说明:https://www.percona.com/doc/percona-xtrabackup/LATEST/installation/yum_repo.html
# 安装yum源
yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
percona-release enable-only tools release
yum install -y percona-xtrabackup-24
xtrabackup -version
# 直接本地安装rpm包
yum localinstall percona-xtrabackup-24-2.4.11-1.el7.x86_64.rpm -y
xtrabackup -version
参数 | 含义 |
---|---|
–user=USER | 指定备份用户,不指定的话为当前系统用户 |
–password=PASSWD | 指定备份用户密码 |
–port=PORT | 指定数据库端口 |
–defaults-group=GROUP-NAME | 在多实例的时候使用 |
–host=HOST | 指定备份的主机,可以为远程数据库服务器 |
–apply-log | 应用 BACKUP-DIR 中的 xtrabackup_logfile 事务日志文件。一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处于不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件使得数据文件处于一致性状态。 |
–apply-log-only | 这个选项使在准备备份(prepare)时,只执行重做(redo)阶段,这对于增量备份非常重要。 |
–database | 指定需要备份的数据库,多个数据库之间以空格分开 |
–defaults-file | 指定mysql的配置文件 |
–copy-back | 将备份数据复制回原始位置 |
–incremental | 增量备份,后面跟要增量备份的路径 |
–incremental-basedir=DIRECTORY | 增量备份时使用指向上一次的增量备份所在的目录 |
–incremental-dir=DIRECTORY | 增量备份还原的时候用来合并增量备份到全量,用来指定全备路径 |
–redo-only | 对增量备份进行合并 |
–rsync | 加快本地文件传输,适用于non-InnoDB数据库引擎。不与–stream共用 |
–safe-slave-backup | 备份时检测从库是否有打开的临时表,如果没有就stop SQL thread开始备份,备份完后start SQL thread;如果有打开的临时表就等,直到–safe-slave-backup-timeout超时。–safe-slave-backup-timeout默认300s,每3s进行一次重试检查,共重试100次。这个参数和–slave-info经常一起使用,为了保证数据的一致性。 |
–slave-info | 在从库进行备份时,该参数会在备份目录下生成xtrabackup_slave_info文件,文件记录主库的binlog日志位置点。在进行数据库恢复,搭建多从库时都需要这个文件。如果在主库进行备份(在主库备份的情况很少,把主库惹怒了只能跑路了),该参数就不起作用了,主库的备份目录下始终会生成文件xtrabackup_binlog_info 记录binlog日志位置点。 |
–no-timestamp | 生成的备份文件不以时间戳为目录. |
备份slave库上的数据。加上此参数会输出master库上的binlog信息
--slave-info
/data/20181129/
下面,若不加--no-timestamp
参数,innobackupex会自动创建一个文件夹+以当前系统时间命名的文件夹,我们的示例中就自定义目录了,当然也可以使用自动生成的目录1.全量备份
/usr/bin/innobackupex /data/backup/full \
--defaults-file=/etc/my.cnf \
--socket=/var/lib/mysql/mysql.sock \
--host=127.0.0.1 \
--user=root \
--password=mvtech123 \
--no-timestamp \
--slave-info \
--parallel=2 \
--throttle=800
2.恢复全量备份
1 关闭mysql
2 重命名mysql的数据目录和日志目录
mv /data/mysql/data /opt/
mv /data/mysql/log /opt/
3 应用日志
innobackupex --apply-log --use-memory=200G /data/20181129/
4 恢复 注:恢复有两种方式--move-back 和--copy-back,move-back速度快,但备份文件被move后就不存在,请根据实际情况进行选择
innobackupex --defaults-file=/etc/my.cnf --move-back /data/20181129/
5 修改权限
chown -R mysql:mysql /data/mysql
6 启动mysql
service mysqld start
流程如下:
innobackupex --defaults-file=/etc/my.cnf --host=127.0.0.1 --user=root --password=mvtech123 --parallel=4 --throttle=400 --incremental-basedir=/data/20181129 --no-timestamp --slave-info --incremental /data/20181130
1 关闭mysql
2 重命名mysql的数据目录和日志目录
mv /data/mysql/data /data/mysql/data_20181129
mv /data/mysql/log /data/mysql/log_20181129
3 对全量备份做prepare
innobackupex --apply-log --redo-only /data/20181129
4 对增量备份做prepare
--redo-only:若只有一个增量备份或是最后那个增量备份文件,那么不需要这个选项,原因同上。也就是说这个选项不能用于最后一个增量备份进行prepare。
--incremental-dir=:此选项对应的目录为增量备份文件的目录
innobackupex --apply-log [--redo-only] /data/20181129 --incremental-dir=/data/20181130
5 查看prepare情况 查看全量备份文件中的xtrabackup_checkpoints
发现last_lsn = 508150192已经和最后一次备份一致
6 恢复 注:恢复有两种方式--move-back 和--copy-back,move-back速度快,但备份文件被move后就不存在,请根据实际情况进行选择
innobackupex --defaults-file=/etc/my.cnf --move-back /data/20181129/
7 修改权限
chown -R mysql:mysql /data/mysql
8 启动mysql
service mysqld start
#!/bin/bash
#This script is xtrabackup full backup mysql
#The Author is mvtech by 2018
#格式化日期
today=$(date +%Y%m%d)
deleteDay=`date -d "-1 days" +%Y%m%d`
echo "--------------------------------------------------------"
echo "-------------------Today is $today----------------------"
echo "--------------------Start backup------------------------"
echo "--------------------------------------------------------"
#定义变量
blxxDir="/data/xtrabackup/$today"
delDir="/data/xtrabackup/$deleteDay"
#创建备份文件夹
mkdir -p $blxxDir
#全量备份
/usr/bin/innobackupex --defaults-file=/etc/my.cnf --socket=/data/mysql/mysql.sock --host=10.99.0.81 --user=weihu --password=Mvtech123!@ $blxxDir --slave-info --no-timestamp --parallel=8 --throttle=800
#删除2天以前的备份
rm -rf $delDir
文件名称 | 文件用途 |
---|---|
ibdata1 | 备份的表空间文件 |
backup-my.cnf | 备份命令用到的配置选项信息; |
xtrabackup_binary | 备份中用到的xtrabackup的可执行文件; |
xtrabackup_binlog_info | 记录导出mysql的binlog信息; mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置 |
xtrabackup_checkpoints | 记录备份方式:备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息; |
xtrabackup_info | 记录此次备份的详细信息 |
xtrabackup_logfile | 备份的重做日志文件 |
xtrabackup_slave_info | 记录备份slave节点时主机上的binlog信息,需要添加--slave-info 参数 |
演示:
# cat /data/20181129/xtrabackup_checkpoints
backup_type = full-backuped #可以看出是全备份
from_lsn = 0 #记录了LSN,日志偏移量
to_lsn = 8096126
last_lsn = 8096126
compact = 0
recover_binlog_info = 0