MySQL中的xtrabackup的原理解析

Percona XtraBackup如何工作

Xtrabackup是基于InnoDB存储引擎灾难恢复的。它复制InnoDB的数据文件,尽管数据文件在内部是非一致性的,但在执行灾难恢复时可以保证这些数据文件是一致的,并且可用。
在InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。

Percona XtraBackup的工作方式

xtrabackup与innobackupex二者区别

xtrabackup包含两个主要的工具,即xtrabackup和innobackupex,二者区别如下:
1 xtrabackup只能备份innodb和xtradb两种引擎的表,而不能备份myisam引擎的表;
2 innobackupex是一个封装了xtrabackup的Perl脚本,支持同时备份innodb和myisam,但在对myisam备份时需要加一个全局的读锁,阻塞写操作,若备份是在从库上进行的话会影响主从同步,造成延迟。对InnoDB表备份不会阻塞读写。还有就是myisam不支持增量备份。

从Percona XtraBackup 2.3版开始,已经用C重写了innobackupex,并将其设置为xtrabackup的符号链接 。innobackupex与2.2版本一样,支持所有功能和语法,但现在已不建议使用,它将在下一个主要版本中删除。新功能的语法不会添加到innobackupex中,而只会添加到xtrabackup中。

备份原理

Xtrabackup在启动时会记住log sequence number(LSN),并且复制所有的数据文件。复制过程需要一些时间,所以这期间如果数据文件有改动,那么将会使数据库处于一个不同的时间点。这时,xtrabackup会运行一个后台进程,用于监视事务日志,并从事务日志复制最新的修改。Xtrabackup必须持续的做这个操作,是因为事务日志是会轮转重复的写入,并且事务日志可以被重用。所以xtrabackup自启动开始,就不停的将事务日志中每个数据文件的修改都记录下来。

Percona XtraBackup将使用备份锁(如果可用)作为一种轻量级替代方法,用读锁刷新表(FLUSH TABLES WITH READ LOCK)。此功能在Percona Server for MySQL 5.6+中可用。Percona XtraBackup使用此选项自动复制非InnoDB数据,以避免阻塞修改InnoDB表的DML查询。当服务器支持备份锁时,xtrabackup首先复制InnoDB数据,运行备份锁表,复制MyISAM表和.frm文件。完成后,将开始备份文件。它将备份.frm、.MRG、.MYD、.MYI、.TRG、.TRN、.ARM、.ARZ、.CSM、.CSV、.par和.opt文件。
(注意:XtraBackup只对MyISAM和其他非InnoDB表进行锁定,并且只有在Percona XtraBackup备份完所有InnoDB/XtraDB数据和日志之后才进行锁定。)

之后,xtrabackup将使用LOCK BINLOG FOR BACKUP来阻止可能更改binary log Pos或Exec_Master_log_Pos或Exec_Gtid_Set的所有操作(即,源二进制日志坐标对应于复制副本上的当前SQL线程状态),如SHOW Master/SLAVE STATUS报告的那样。然后,xtrabackup将完成复制REDO日志文件并获取二进制日志坐标。完成此操作后,xtrabackup将解锁二进制日志和表 。

最后,二进制日志位置将被打印到STDERR,如果一切正常,xtrabackup将退出并返回0。 请注意,xtrabackup的STDERR没有写入任何文件。您必须将其重定向到一个文件,例如xtrabackup OPTIONS 2> backupout.log.

Xtrabackup工具的备份过程原理图
全库备份

在这里插入图片描述

1 首先会启动一个xtrabackup_log后台检测的进程,实时检测mysql redo的变化,一旦发现redo有新的日志写入,立刻将日志写入到日志文件xtrabackup_log中 (thread 1 redolog扫描线程)
2 启动复制innodb的数据文件和系统表空间文件idbdata1到对应的以默认时间戳为备份目录的地方(thread 2 数据库表copy线程)
3 复制结束后,执行flush table with read lock操作 (启动非innodb引擎的copy线程,加全局读锁。)
4 复制.frm .myd .myi文件
5 并且在这一时刻获得binary log 的位置 (非innodb引擎的文件拷贝完毕后,停止copy线程,然后停止redo线程,在停止redo线程之前,redo线程一直在拷贝,到最新的日志)
6 将表进行解锁unlock tables
7 停止xtrabackup_log进程

增量备份

增量备份主要是通过拷贝innodb中有变更的页(指的是LSN大于xtrabackup_checkpoints中的LSN号)。增量备份实际上不会将数据文件与以前备份的数据文件进行比较。因此,在部分备份之后运行增量备份可能会导致数据不一致。增量备份只需读取页面并将其LSN与上次备份的LSN进行比较。但是,您仍然需要完整备份来恢复增量更改;如果没有完整备份作为基础,那么增量备份将毫无用处。您可以使用–incremental-lsn选项来执行增量备份,甚至不需要以前的备份(如果您知道它的lsn的话)。增量备份是基于全备的,第一次增量备份的数据是基于上一次全备,之后的每一次增倍都是基于上一次的增倍,最终达到一致性的增倍,增倍的过程中,和全备很类似,区别在于第二步
在这里插入图片描述

恢复原理

在准备(prepare)阶段,Percona XtraBackup使用复制的事务日志文件对复制的数据文件执行崩溃恢复。完成后,数据库就可以恢复和使用了。

备份MyISAM和InnoDB表最终会处于一致,在准备(prepare)过程结束后,InnoDB表数据已经前滚到整个备份结束的点,而不是回滚到xtrabackup刚开始时的点。这个时间点与执行FLUSH TABLES WITH READ LOCK的时间点相同,所以myisam表数据与InnoDB表数据是同步的。类似oracle的,InnoDB的prepare过程可以称为recover(恢复),myisam的数据复制过程可以称为restore(还原)。

要使用xtrabackup恢复备份,可以使用 xtrabackup --copy-back 或选项xtrabackup --move-back

xtrabackup将从my.cnf变量datadir, innodb_data_home_dir,innodb_data_file_path, innodb_log_group_home_dir中读取并检查目录是否存在。

它将首先复制MyISAM表、索引等(.frm、.MRG、.MYD、.MYI、.TRG、.TRN、.ARM、.ARZ、.CSM、.CSV、par和.opt文件),然后复制InnoDB表和索引,最后复制日志文件。它将在复制文件时保留文件的属性,您可能需要在启动数据库服务器之前将文件的所有权更改为mysql,因为它们将由创建备份的用户拥有。

或者,可以使用xtrabackup --move back选项恢复备份。此选项类似于xtrabackup --copy-back,唯一的区别是它不复制文件,而是将文件移动到目标位置。由于此选项会删除备份文件,因此必须谨慎使用。在没有足够的可用磁盘空间来存放数据文件及其备份副本的情况下,它非常有用。

Xtrabackup工具的恢复过程原理图
全库恢复

准备(–prepare)
在准备阶段,由于备份是将所有物理库表等文件复制到备份目录,而整个过程需要持续一段时间,在此期间,物理文件可能改变,这将导致最终备份结果处于不一致状态(所有文件不是处于同一个时间点)。恢复期间,–use-memory选项可以加速prepare过程,如果系统可用内存够大的话,该值缺省被设置为100MB。

cat xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 1626007
last_lsn = 1628149
compact = 0
recover_binlog_info = 1

从xtrabackup_checkpoints文件中可以看出,备份开始前InnoDB最后一次checkpoint是在to_lsn = 1626007位置,备份结束后InnoDB最后一次checkpoint是在last_lsn = 1628149,因此,就需要xtrabackup_logfile(Redo Log)将监控复制的所有事务日志to_lsn–>last_lsn逐一应用(提交、回滚)到所有物理库表文件,从而达到最终一致性。

恢复(–copy-back)
在恢复阶段,所作的事情就很简单了,将所有备份文件复制到datadir(前提是清空文件夹)中即可。

在这里插入图片描述

增量备份的恢复

和全库恢复类似,也需要两步

  1. 数据文件的恢复分3部分
    全备
    增量备份
    xtrabackup_log
  2. 对未提交事务的回滚
    在这里插入图片描述

增量备份恢复示例

创建增量备份

要进行增量备份,请像往常一样从完整备份开始。该 xtrabackup二进制写入一个名为xtrabackup_checkpoints到备份的目标目录。该文件包含一行显示 to_lsn,这是备份结束时数据库的LSN。 使用以下命令创建完整备份:

$ xtrabackup --backup --target-dir=/data/backups/base

如果查看xtrabackup_checkpoints文件,根据您的LSN编号,应该会看到类似的内容:

backup_type = full-backuped
from_lsn = 0
to_lsn = 1626007
last_lsn = 1626007
compact = 0
recover_binlog_info = 1

现在,您已经有了完整备份,您可以基于它进行增量备份。使用以下命令:

$ xtrabackup --backup --target-dir=/data/backups/inc1 --incremental-basedir=/data/backups/base

/data/backups/inc1/目录现在应该包含增量文件,例如ibdata1.delta和test/table1.ibd.delta。这些代表了自LSN 1626007以来的变化。如果检查此目录中的xtrabackup_checkpoints文件,应该会看到与以下内容类似的内容:

backup_type = incremental
from_lsn = 1626007
to_lsn = 4124244
last_lsn = 4124244
compact = 0
recover_binlog_info = 1

from_lsn是备份的起始lsn,对于增量备份,它必须与上一个基本备份的to_lsn(如果是最后一个检查点)相同。
现在可以将此目录用作另一个增量备份的基础:

$ xtrabackup --backup --target-dir=/data/backups/inc2 --incremental-basedir=/data/backups/inc1

此文件夹还包含xtrabackup_checkpoints:

backup_type = incremental
from_lsn = 4124244
to_lsn = 6938371
last_lsn = 7110572
compact = 0
recover_binlog_info = 1

在这种情况下,您可以看到to_lsn(最后一个检查点lsn)和last_lsn(最后一个复制的lsn)之间存在差异,这意味着在备份过程中服务器上有一些通信量。

准备增量备份

增量备份的xtrabackup --prepare 步骤与完整备份的步骤不同。在完全备份中,执行两种类型的操作以使数据库保持一致:根据数据文件从日志文件重放已提交的事务,并回滚未提交的事务。在准备增量备份时,必须跳过未提交事务的回滚,因为备份时未提交的事务可能正在进行中,并且很可能会在下一次增量备份中提交。您应该使用xtrabackup --apply-log-only选项来防止回滚阶段。( 提醒:如果您不使用该 xtrabackup --apply-log-only选项阻止回滚阶段,则增量备份将无用。事务回滚后,无法再应用增量备份。)

要准备基本备份,您需要照常运行xtrabackup --prepare,但要防止回滚阶段:

$ xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base

输出类似于以下内容的文本结尾:

InnoDB: Shutdown completed; log sequence number 1626007
161011 12:41:04 completed OK!
日志序列号应该与前面看到的基本备份的to_lsn匹配。

要将第一个增量备份应用于完整备份,请运行以下命令:

$ xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base --incremental-dir=/data/backups/inc1

这会将增量文件应用于/data/backups/base中的文件,从而将它们在时间上向前滚动到增量备份的时间。然后像往常一样将重做日志应用于结果。最后的数据在/data/backups/base中,而不是在incremental目录中。您应该看到类似于以下内容的输出:

incremental backup from 1626007 is enabled.
xtrabackup: cd to /data/backups/base
xtrabackup: This target seems to be already prepared with --apply-log-only.
xtrabackup: xtrabackup_logfile detected: size=2097152, start_lsn=(4124244)

xtrabackup: page size for /tmp/backups/inc1/ibdata1.delta is 16384 bytes
Applying /tmp/backups/inc1/ibdata1.delta to ./ibdata1…

161011 12:45:56 completed OK!
同样,LSN应该与您先前检查第一次增量备份时看到的内容相匹配。如果从/data/backups/base还原文件,则应该看到第一次增量备份时数据库的状态。

准备第二个增量备份是一个类似的过程:将增量应用于(已修改的)基础备份,您将及时将其数据前滚到第二个增量备份的点:

$ xtrabackup --prepare --target-dir=/data/backups/base --incremental-dir=/data/backups/inc2

注意:
xtrabackup合并除最后一个增量之外的所有增量时,应使用–apply-log-only 。这就是为什么上一行不包含xtrabackup --apply log only选项的原因。即使在最后一步中使用了xtrabackup --apply-log-only ,备份仍然是一致的,但在这种情况下,服务器将执行回滚阶段。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值