程序员人生 网站导航

MySQL-物理备份-Percona XtraBackup 备份原理

栏目:数据库应用时间:2016-07-06 08:50:01

Percona XtraBackup(简称PXB)是 Percona 公司开发的1个用于 MySQL 数据库物理热备的备份工具,支持 MySQl(Oracle)、Percona Server 和 MariaDB,并且全部开源,真可谓是业界良知。

工具集
软件包安装完后1共有4个可履行文件,以下:
usr ├── bin │ ├── innobackupex │ ├── xbcrypt │ ├── xbstream │ └── xtrabackup

其中最主要的是 innobackupex 和 xtrabackup,前者是1个 perl 脚本,后者是 C/C++ 编译的2进制。

xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 mysqld server 没有交互;innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和 mysqld server 发送命令进行交互,如加读锁(FTWRL)、获得位点(SHOW SLAVE STATUS)等。简单来讲,innobackupex 在 xtrabackup 之上做了1层封装。

1般情况下,我们是希望能备份 MyISAM 表的,虽然我们可能自己不用 MyISAM 表,但是 mysql 库下的系统表是 MyISAM 的,因此备份基本都通过 innobackupex 命令进行;另外1个缘由是我们可能需要保存位点信息。

另外2个工具相对小众些,xbcrypt 是加解密用的;xbstream 类似于tar,是 Percona 自己实现的1种支持并发写的流文件格式。两都在备份和解压时都会用到(如果备份用了加密和并发)。

本文的介绍的主角是 innobackupex 和 xtrabackup


通讯方式

2个工具之间的交互和调和是通过控制文件的创建和删除来实现的,主要文件有:

  • xtrabackup_suspended_1
  • xtrabackup_suspended_2
  • xtrabackup_log_copied

举个栗子,我们来看备份时 xtrabackup_suspended_2 是怎样来调和2个工具进程的

  1. innobackupex 在启动 xtrabackup 进程后,会1直等 xtrabackup 备份完 InnoDB 文件,方式就是等待 xtrabackup_suspended_2 这个文件被创建出来;
  2. xtrabackup 在备完 InnoDB 数据后,就在指定目录下创建出这个文件,然后等这个文件被 innobackupex 删除;
  3. innobackupex 检测到文件 xtrabackup_suspended_2 被创建出来后,就继续往下走;
  4. innobackupex 在备份完非 InnoDB 表后,删除 xtrabackup_suspended_2 这个文件,这样就通知 xtrabackup可以继续了,然后等 xtrabackup_log_copied 被创建;
  5. xtrabackup 检测到 xtrabackup_suspended_2 文件删除后,就能够继续往下了。

是否是感觉有点不可思议,通过文件是不是存在来控制进程,这类方式非常的不靠谱,由于非常容易被外部干扰,比如文件被他人误删掉,或2个正在跑的备份控制文件误放在同1个目录下,就等着备份乱掉吧,但是 Percona 就是这么干的。

之所以这么弄,估计主要是由于 perl 和 C 2进制2个进程,没有既好用又方便的通讯方式,弄个协议啥的太麻烦了。但是官方也觉得这类方式不靠谱,11年就弄了个 blueprint 要用C重写 innobackupex,终究在2.3 版本实现了,innobackupex 功能全部集成到 xtrabackup 里面,只有1个 binary,另外为了使用上的兼容斟酌,innobackupex作为 xtrabackup 的1个软链。对2次开发来讲,2.3 摆脱了之前2个进程协作的负担,架构上明显要好过之前版本。斟酌到 perl + C 这类架构的长时间存在,大多数读者朋友也基本用的2.3之前版本,本文的介绍也是基于老的架构(2.2版本),但是原理和2.3是1样的,只是实现上的差别。


备份进程

全部备份进程以下图:

PXB备份过程
  1. innobackupex 在启动后,会先 fork 1个进程,启动 xtrabackup进程,然后就等待 xtrabackup 备份完 ibd 数据文件;
  2. xtrabackup 在备份 InnoDB 相干数据时,是有2种线程的,1种是 redo 拷贝线程,负责拷贝 redo 文件,1种是 ibd 拷贝线程,负责拷贝 ibd 文件;redo 拷贝线程只有1个,在 ibd 拷贝线程之前启动,在 ibd 线程结束后结束。xtrabackup 进程开始履行后,先启动 redo 拷贝线程,从最新的 checkpoint 点开始顺序拷贝 redo 日志;然后再启动 ibd 数据拷贝线程,在 xtrabackup 拷贝 ibd 进程中,innobackupex 进程1直处于等待状态(等待文件被创建)。
  3. xtrabackup 拷贝完成idb后,通知 innobackupex(通过创建文件),同时自己进入等待(redo 线程依然继续拷贝);
  4. innobackupex 收到 xtrabackup 通知后,履行FLUSH TABLES WITH READ LOCK (FTWRL),获得1致性位点,然后开始备份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷贝非 InnoDB 文件进程中,由于数据库处于全局只读状态,如果在业务的主库备份的话,要特别谨慎,非 InnoDB 表(主要是MyISAM)比较多的话整库只读时间就会比较长,这个影响1定要评估到。
  5. 当 innobackupex 拷贝完所有非 InnoDB 表文件后,通知 xtrabackup(通过删文件) ,同时自己进入等待(等待另外一个文件被创建);
  6. xtrabackup 收到 innobackupex 备份完非 InnoDB 通知后,就停止 redo 拷贝线程,然后通知 innobackupexredo log 拷贝完成(通过创建文件);
  7. innobackupex 收到 redo 备份完成通知后,就开始解锁,履行 UNLOCK TABLES
  8. 最后 innobackupex 和 xtrabackup 进程各自完成扫尾工作,如资源的释放、写备份元数据信息等,innobackupex 等待 xtrabackup 子进程结束后退出。

在上面描写的文件拷贝,都是备份进程直接通过操作系统读取数据文件的,只在履行 SQL 命令时和数据库有交互,基本不影响数据库的运行,在备份非 InnoDB 时会有1段时间只读(如果没有MyISAM表的话,只读时间在几秒左右),在备份 InnoDB 数据文件时,对数据库完全没有影响,是真实的热备。

InnoDB 和非 InnoDB 文件的备份都是通过拷贝文件来做的,但是实现的方式不同,前者是以page为粒度做的(xtrabackup),后者是 cp 或 tar 命令(innobackupex),xtrabackup 在读取每一个page时会校验 checksum 值,保证数据块是1致的,而 innobackupex 在 cp MyISAM 文件时已做了flush(FTWRL),磁盘上的文件也是完全的,所以终究备份集里的数据文件都是写入完全的。


增量备份

PXB 是支持增量备份的,但是只能对 InnoDB 做增量,InnoDB 每一个 page 有个 LSN 号,LSN 是全局递增的,page 被更改时会记录当前的 LSN 号,page中的 LSN 越大,说明当前page越新(最近被更新)。每次备份会记录当前备份到的LSN(xtrabackup_checkpoints 文件中),增量备份就是只拷贝LSN大于上次备份的page,比上次备份小的跳过,每一个 ibd 文件终究备份出来的是增量 delta 文件。

MyISAM 是没有增量的机制的,每次增量备份都是全部拷贝的。

增量备份进程和全量备份1样,只是在 ibd 文件拷贝上有不同。


恢复进程

如果看恢复备份集的日志,会发现和 mysqld 启动时非常相似,其实备份集的恢复就是类似 mysqld crash后,做1次 crash recover。

恢复的目的是把备份集中的数据恢复到1个1致性位点,所谓1致就是指原数据库某1时间点各引擎数据的状态,比如 MyISAM 中的数据对应的是 15:00 时间点的,InnoDB 中的数据对应的是 15:20 的,这类状态的数据就是不1致的。PXB 备份集对应的1致点,就是备份时FTWRL的时间点,恢复出来的数据,就对应原数据库FTWRL时的状态。

由于备份时 FTWRL 后,数据库是处于只读的,非 InnoDB 数据是在持有全局读锁情况下拷贝的,所以非 InnoDB 数据本身就对应 FTWRL 时间点;InnoDB 的 ibd 文件拷贝是在 FTWRL 前做的,拷贝出来的不同 ibd 文件最后更新时间点是不1样的,这类状态的 ibd 文件是不能直接用的,但是 redo log 是从备份开始1直延续拷贝的,最后的 redo 日志点是在持有 FTWRL 后获得的,所以终究通过 redo 利用后的 ibd 数据时间点也是和 FTWRL 1致的。

所以恢复进程只触及 InnoDB 文件的恢复,非 InnoDB 数据是不动的。备份恢复完成后,就能够把数据文件拷贝到对应的目录,然后通过mysqld来启动了。


------分隔线----------------------------
------分隔线----------------------------

最新技术推荐