在本博客中,"mysql"是一个系列文章,这些文章主要对mysql/mariadb的常用知识点进行了总结,每一篇博客总结的知识点有所不同,具体内容可参考mysql文章列表。
mysql文章列表直达链接:mysql知识点总结
xtrabackup可以对InnoDB数据进行全量备份,增量备份,差量备份。
之前的文章已经总结了怎样使用xtrabackup对InnoDB数据进行全量备份,参考链接如下:
那么此处,我们就来总结一下怎样使用xtrabackup对InnoDB数据进行增量备份或者差量备份。
增量备份与差量备份的概念在此就不啰嗦了,如果你还不太明白,可以参考如下连接:
全量备份是差量与增量的基础,因为差量备份只能针对于上一次全量备份,增量备份则可以针对上一次任何一种备份,上一次备份可以是全量、差量、或者增量,但是不管怎么样,总是要有一份全量备份作为基础的,不管是增量备份还是差量备份,都是对于innodb表来说的,对于myisam表,即使执行了所谓的"增量"备份,其实也是全量备份。
所以,模拟整个过程,我们先备份一个全量出来,备份全量的xtrabackup命令如下,如果还不理解,可以参考之前的文章。
Shell
innobackupex -p123123 /backup
1
innobackupex -p123123 /backup
全量备份完成后,在/backup目录下,可以看到一个以备份时间为名称的备份文件夹。
Shell
# ls /backup
2017-04-08_13-36-11
1
2
# ls /backup
2017-04-08_13-36-11
查看本次全量备份的xtrabackup_checkpoints文件,可以发现,此文件中记录了此次备份的类型为"全量备份",备份page的LSN范围为0到61715333。
Shell
# cat /backup/2017-04-08_13-36-11/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 61715333
last_lsn = 61715333
compact = 0
recover_binlog_info = 0
1
2
3
4
5
6
7
# cat /backup/2017-04-08_13-36-11/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 61715333
last_lsn = 61715333
compact = 0
recover_binlog_info = 0
好了,全量备份完成了,现在修改一下数据库中的数据
假设,时光飞逝,一天就这么过去了,我们什么也没干,就是删除了一条数据,新增了一条数据而已,那么现在,我们要进行增量备份了。
增量备份是针对上一次备份来说的,所以,我们在进行增量备份时,需要指定以哪个备份作为上一次的备份,增量备份的示例命令如下
Shell
innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-36-11/
1
innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-36-11/
上述命令中的--incremental选项表示本次备份是一个增量备份(其实这次备份既可以算是增量,也可以算作差量),本次增量备份将备份至/backup目录下,本次增量备份是针对于/backup/2017-04-08_13-36-11/的增量,就是这么简单,聪明如你一定已经想到了,使用上述命令也可以实现差量备份,如果想要实现差量备份,只要将上述命令中的--incremental-basedir选项的值每次都设定为全量备份的路径即可,其实这次备份也可以理解为一次差量备份。
执行上述增量备份命令后,查看/backup目录,发现已经存在刚才增量备份的目录了。
Shell
# ls /backup/
2017-04-08_13-36-11 2017-04-08_13-41-59
1
2
# ls /backup/
2017-04-08_13-36-11 2017-04-08_13-41-59
查看增量备份目录中的xtrabackup_checkpoints文件内容,发现其中已经为我们标注好了,本次备份是一个增量备份,并且,为我们记录了本次备份的起始LSN与结束LSN,细心如你一定发现了,本次备份的起始LSN与上次全量备份的结束LSN号码相同。
Shell
# cat /backup/2017-04-08_13-41-59/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 61715333
to_lsn = 61716055
last_lsn = 61716055
compact = 0
recover_binlog_info = 0
1
2
3
4
5
6
7
# cat /backup/2017-04-08_13-41-59/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 61715333
to_lsn = 61716055
last_lsn = 61716055
compact = 0
recover_binlog_info = 0
假设,增量备份完成后,又开始了新的一天,又开始了新的工作,又开始改数据库了。
工作效率真够低的,一天就改了这么点数据,其他的工作都没有完成,好吧,此刻又要开始新的增量备份了。
同样,这次的增量备份是基于上一次备份进行的,所以,我们要指定上一次的备份位置,只不过,上一次备份也是增量备份罢了。
Shell
innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-41-59
1
innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-41-59
查看这一次增量备份的checkpoints文件,可以看到,这次备份起始的LSN号与上一次备份结束的LSN号相同。
Shell
# cat /backup/2017-04-08_14-01-16/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 61716055
to_lsn = 61716350
last_lsn = 61716350
compact = 0
recover_binlog_info = 0
1
2
3
4
5
6
7
# cat /backup/2017-04-08_14-01-16/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 61716055
to_lsn = 61716350
last_lsn = 61716350
compact = 0
recover_binlog_info = 0
再次查看备份目录,发现已经存在了一个全量备份目录与两个增量备份目录。
Shell
# ls /backup
2017-04-08_13-36-11 2017-04-08_13-41-59 2017-04-08_14-01-16
1
2
# ls /backup
2017-04-08_13-36-11 2017-04-08_13-41-59 2017-04-08_14-01-16
现在,我们要使用上述3个备份将数据还原(此处不考虑时间点还原),为了不影响现在的服务运行,我们将备份还原到一台新的服务器上。
如果在另一台mysql服务器上恢复,则先确保已经安装了同样版本的mysql,并且安装了xtrabackup。
将所有备份拷贝至新的mysql服务器上
Shell
scp -r /backup/* 192.168.1.120:/testdir/
1
scp -r /backup/* 192.168.1.120:/testdir/
在之前的文章中,我们在恢复全量备份时,只需要对全量备份进行准备操作即可,但是此时,我们除了全量备份,还有增量备份, 由于有多个备份,所以准备工作要进行多次,首先,先对全量备份进行准备工作。
Shell
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/
1
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/
细心如你已经发现了,上述命令与前文中的命令有所不同,上述命令多出了一个--redo-only选项,这个选项表示在进行准备(应用日志)工作时,只进行redo操作,因为在备份开始时,有的事务日志已经提交了,但是还没有完全应用到数据文件中,有的事务日志还没有提交,这些没有提交的事务需要进行回滚操作,在进行"准备"工作时,如果添加了--redo-only选项,则只会重做已提交但是未应用的事务,而不会回滚未提交的事务,为什么前文中的准备工作中,没有添加--redo-only选项呢,那是因为,前文中只还原了一个全量备份,全量备份之后没有任何其他备份需要合并,而此刻则不同,除了全量备份,后面还有对应的增量备份,那么全量备份中未提交的事务有可能在后面的增量备份中已经提交了,所以,在准备"最后一份备份"之前的"备份"时,都不用进行回滚操作,只在最后一次备份中进行回滚操作即可。
上述命令执行完成后,完全备份已经准备完成。
现在要准备增量数据了,我们现在要做的是,将第一次进行的增量备份合并到之前准备好的完全备份中,示例命令如下。
Shell
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_13-41-59
1
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_13-41-59
上述命令中仍然使用了--redo-only选项,并且使用了--incremental-dir选项,此选项对应的目录为增量备份文件的目录,上述命令表示对增量备份进行准备工作,并且把准备好的增量备份合并到对应的全量备份中。
执行完上述命令后,则表示第一份增量备份已经整理完毕,并且已经将增量合并到了对应的全量备份中,如果此时,查看全量备份中的 xtrabackup_checkpoints
文件,会发现全量备份的备份类型已经变为了"log-applied",如下所示,也就是说,这个备份已经经历过了日志应用的过程(已经做过了准备工作),而且,对应的最大的LSN号码为61716055,此LSN正是第一次增量的结束LSN,也就是说,我们已经将第一次增量与全量整合在了一起。
Shell
# cat /testdir/2017-04-08_13-36-11/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 61716055
last_lsn = 61716055
compact = 0
recover_binlog_info = 0
1
2
3
4
5
6
7
# cat /testdir/2017-04-08_13-36-11/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 61716055
last_lsn = 61716055
compact = 0
recover_binlog_info = 0
好了,第一份增量已经与全量完美的整合在了一起,现在需要合并最后一份增量了,示例命令如下。
Shell
innobackupex --apply-log --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_14-01-16
1
innobackupex --apply-log --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_14-01-16
因为这是最后一份备份数据,所以并不用添加--redo-only选项,事务日志需要应用,该提交的提交,该回滚的回滚,上述命令中,--incremental-dir对应的目录为最后一次增量备份的目录,表示准备最后一次的增量备份,并且将准备好的增量备份合并到上次准备好的全量备份中。
上述命令执行成功后,再次查看对应的全量备份目录中的xtrabackup_checkpoints文件,发现对应的LSN号码已经变为最后一次增量备份的结束LSN号码了。
Shell
# cat /testdir/2017-04-08_13-36-11/xtrabackup_checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 61716350
last_lsn = 61716350
compact = 0
recover_binlog_info = 0
1
2
3
4
5
6
7
# cat /testdir/2017-04-08_13-36-11/xtrabackup_checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 61716350
last_lsn = 61716350
compact = 0
recover_binlog_info = 0
到目前为止,所有准备工作已经完成,我们已经把所有增量备份都合并到了最初的第一份全量备份中,现在,我们只要通过这一份全量备份即可恢复数据库。
完成准备工作后,确定新的MySQL服务器上的mysql服务已经停止,确定对应的数据目录中没有任何文件,那么,我们删除对应的数据文件与日志。
Shell
systemctl stop mariadb
rm -rf /var/lib/mysql/*
1
2
systemctl stop mariadb
rm -rf /var/lib/mysql/*
完成上述工作后,将准备好的数据还原回对应的数据目录中,没错,只将最后合并完成的那个全量备份还原即可,因为之前的准备工作中,我们已经将所有增量数据都合并到这个全量中了。
Shell
innobackupex --datadir=/var/lib/mysql --copy-back /testdir/2017-04-08_13-36-11
1
innobackupex --datadir=/var/lib/mysql --copy-back /testdir/2017-04-08_13-36-11
数据还原拷贝完成后,将对应数据目录中的文件的属主属组设置为mysql用户
Shell
chown -R mysql: /var/lib/mysql/
1
chown -R mysql: /var/lib/mysql/
完成上述步骤后,启动mysql服务,当然,实际还原时最好将对应的配置文件(例如my.cnf)也都还原了,所有数据还原后,再启动mysql服务。
Shell
systemctl start mariadb
1
systemctl start mariadb
登录数据库,查看对应的数据,都已经被正常的还原了,当然,我们并没有进行时间点还原。
通过上文,我们已经能够通过xtrabackup对innodb数据库进行增量备份并还原了,那么,我们把整个过程中用到的语句总结一下,方便我们回顾吧。
xtrabackup通过全量备份与增量备份还原数据库的命令总结:
备份命令如下
首先进行全量备份
Shell
# innobackupex -p123123 /backup
1
# innobackupex -p123123 /backup
Shell
# ls /backup
2017-04-08_13-36-11
1
2
# ls /backup
2017-04-08_13-36-11
其次针对上次全量备份进行增量备份,或者差量备份
Shell
# innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-36-11/
1
# innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-36-11/
Shell
# ls /backup/
2017-04-08_13-36-11 2017-04-08_13-41-59
1
2
# ls /backup/
2017-04-08_13-36-11 2017-04-08_13-41-59
针对上一次增量或者差量做增量备份,因为如下命令中--incremental-basedir选项指定的路径为上一次的增量(差量),所以,这次备份一定是增量备份,如果如下命令的--incremental-basedir选项对应的目录仍然为原来的全量备份,那么这次备份即为差量备份。
Shell
# innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-41-59
1
# innobackupex -p123123 --incremental /backup --incremental-basedir=/backup/2017-04-08_13-41-59
Shell
# ls /backup
2017-04-08_13-36-11 2017-04-08_13-41-59 2017-04-08_14-01-16
1
2
# ls /backup
2017-04-08_13-36-11 2017-04-08_13-41-59 2017-04-08_14-01-16
当然,上述增量备份的次数由备份策略决定,此处用于示例,只进行两次增量。假设我们需要通过这三次备份进行数据恢复。
恢复命令如下
为了不影响现在的服务运行,我们将备份还原到一台新的服务器上,先确保新机器已经安装了同样版本的mysql,并且安装了xtrabackup。
将所有备份拷贝至新的mysql服务器上
Shell
scp -r /backup/* 192.168.1.120:/testdir/
1
scp -r /backup/* 192.168.1.120:/testdir/
先对最开始的全量备份进行prepare工作,因为后面还有增量备份,所以此处prepare时使用--redo-only选项。
Shell
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/
1
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/
现在准备增量备份,如果有多个增量备份,最后一个增量之前的所有增量都可以使用类似如下命令进行prepare(唯一需要改变的就是--incremental-dir选项对应的增量目录),将当前增量prepare并合并到完全备份中,命令如下。
Shell
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_13-41-59
1
innobackupex --apply-log --redo-only --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_13-41-59
准备最后一个增量备份,并且合并到全量备份中。
Shell
innobackupex --apply-log --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_14-01-16
1
innobackupex --apply-log --use-memory=1G /testdir/2017-04-08_13-36-11/ --incremental-dir=/testdir/2017-04-08_14-01-16
所有备份的准备(prepare)工作已经完成,完成准备工作后,确定新的MySQL服务器上的mysql服务已经停止,确定对应的数据目录中没有任何文件,那么,我们删除对应的数据文件与日志。
Shell
systemctl stop mariadb
rm -rf /var/lib/mysql/*
1
2
systemctl stop mariadb
rm -rf /var/lib/mysql/*
完成上述工作后,将准备好的数据还原回对应的数据目录中,只还原最终准备好的全量备份即可
Shell
innobackupex --datadir=/var/lib/mysql --copy-back /testdir/2017-04-08_13-36-11
1
innobackupex --datadir=/var/lib/mysql --copy-back /testdir/2017-04-08_13-36-11
数据还原拷贝完成后,将对应数据目录中的文件的属主属组设置为mysql用户
Shell
chown -R mysql: /var/lib/mysql/
1
chown -R mysql: /var/lib/mysql/
完成上述步骤后,启动mysql服务,当然,实际还原时还需要将对应的配置文件(例如my.cnf)也都还原了,所有数据还原后,再启动mysql服务。
Shell
systemctl start mariadb
1
systemctl start mariadb
完成上述步骤后,即恢复完成(未涉及时间点还原)。