MySQL物理备份-Percona XtraBackup 备份/恢复原理

前言

Percona XtraBackup(简称 PXB ) 是 Percona 公司开发的一个用于 MySQL 数据库物理热备的备份工具。支持MySQL(Oracle)、Percona Server 和 MariaDB。

工具集

# 下载安装包
$ wget wget https://downloads.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.23-16/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.23-16.1.el7.x86_64.rpm
$ yum -y install ./percona-xtrabackup-80-8.0.23-16.1.el7.x86_64.rpm 
$ xtrabackup -version
xtrabackup: recognized server arguments: --server-id=1 --datadir=/data/mysql --innodb_file_per_table=1 --log_bin=/var/log/mysql/mysql-bin --innodb_directories=/opt/data8.0/tmpdata 
xtrabackup version 8.0.23-16 based on MySQL server 8.0.23 Linux (x86_64) (revision id: 934bc8f)

# 工具目录
usr
├── bin
│   ├── xbcrypt      # 加密解密工具
│   ├── xbstream     # 类似于tar,是Percona 自己实现的一种支持并发写的流文件格式
│   └── xtrabackup   # 备份工具

备份过程

XtraBackup 备份流程如下图: file

PXB 备份过程说明

  • innobackupex 在启动后,会先 fork 一个进程,启动 xtrabackup 进程,然后等待 xtrabackup 备份完 ibd 数据文件;

  • xtrabackup 在备份 InnoDB 相关数据时,是有 两种线程

    • 1种是 redo 拷贝线程,负责拷贝 redo 文件,用于从最新的 checkpoint 点开始顺序拷贝 redo.log 文件;

    • 1种是 ibd 拷贝线程,负责拷贝 ibd 文件;redo 拷贝线程只有一个,在 ibd 拷贝线程之前启动,在 ibd 线程结束后结束

    • xtrabackup 进程开始执行后,先启动 redo 拷贝线程,从最新的 checkpoint 点开始顺序拷贝 redo 日志; 然后再启动 ibd 数据拷贝线程,在 xtrabackup 拷贝 ibd 过程中,innobackupex 进程一直处于等待状态(等待文件被创建)。

  • xtrabackup 拷贝完成 idb 后,通知 innobackupex (通过创建文件),同时自己进入等待(redo 线程仍然继续拷贝);

  • innobackupex 收到 xtrabackup 通知后,执行 FLUSH TABLES WITH READ LOCK(FTWRL) ,获取到一致性位点,然后开始备份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷贝非 InnoDB 文件过程中,因为数据库处于全局只读状态,,如果在业务的主库备份,需要注意评估主库中的非 InnoDB 表的大小,数据量越大影响越大;

  • innobackupex 拷贝完所有非 InnoDB 表文件后,通知 xtrabackup (通过删文件),同时自己进入等待状态(等待另一个文件被创建);

  • xtrabackup 收到 innobackupex 备份完非 InnoDB 通知后,就停止 redo 拷贝线程,然后通知 innobackupex redo log 拷贝完成(通过创建文件通知);

  • innobackupex 收到 redo 备份完成的通知后,就开始解锁,执行 UNLOCK TABLES;

  • 最后 innobackupexxtrabackup 进程各自完成收尾工作,如资源的释放、写备份元数据等,innobackupex 等待 xtrabackup 子进程结束后退出。

在上面描述的文件拷贝,都是备份进程直接通过操作系统读取数据文件的,只在执行 SQL 命令时和数据库有交互,基本不影响数据库的运行,在备份非 InnoDB 时会有一段时间时间只读(如果没有Myisam表的话,只读时间在几秒内左右,8.0+后系统表全是InnoDB了) ,在备份 InnoDB 数据文件时,对数据库完全没有任何影响,是真正的热备。

InnoDB 和非 InnoDB 文件的备份都是通过拷贝文件来做的,但是实现的方式不同

  • InnoDB: xtrabackuppage 为粒度做的复制,xtrabackup 在读取每个 page 时会校验 checksum 值,保证数据块是一致的;
  • 非InnoDB: 这个是 innobackupex 使用 cp 或者 tar 命令来做的复制,因为 innobackupex 在 cp MyISAM 文件时已经做了 flush (加了 FTWRL锁),此时磁盘上的文件是完成,也没有写入,所以最终备份集里的数据文件都是写入完整的。 file

增量备份

PXB 是支持增量备份的,但是只针对 InnoDB 做增量,InnoDB 每个 page 都有自己的 LSN 号,LSN 号码是全局递增唯一的,page 被更改时(数据量的增加或减少,都是page的变化)会记录当前的 LSN 号码,page 中的 LSN 越大,说明当前 page 越新(最近被更新)。每次备份会记录都会把当前任务结束的 LSN 号码记录到 xtrabackup_checkpoints 文件中,增量备份就是只拷贝 LSN 大于上次备份的 page,比上次备份小的跳过,每个 ibd 文件最终备份出来的是增量 data 文件。

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

增量备份过程和全量备份一样,只是在 ibd 文件拷贝上有所不同 file

问题: 如果一个数据页原本不是在增量范围内的,在增量备份的过程中,数据页更新了,那么增量备份是否会涵盖这个数据页?

解决方案: 通过恢复数据的时候,在 prepare 阶段进行回放 redo log,解决数据新旧不一致的问题 在增量备份的过程中,如果数据页被更新了,那数据文件中的这个数据页有可能 被拷贝到备份中,也可能没有被拷贝到备份中,但是这个更新信息一定会被redo log 记录,并被记录在备份中。所在恢复过程中,redo log 会被“安全地” 回放成功,达到新旧数据一致的目的。

恢复过程

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

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

PXB 备份集对应的一致点,就是备份的 FTWRL 的时间点,恢复出来的数据,就对应原数据库 FTWRL 时的状态 因为备份时 FTWRL 候,数据库是处于只读状态,

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

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

恢复流程说明

  • 先还原一个全量备份到临时目录;
  • 开始还原增量备份,将增量备份中的增量数据文件,覆盖到全量备份所在的临时目录中;
  • 将增量备份中的 redo log,回放到全量备份所在的临时目录中;
  • 将其它文件覆盖到临时目录中;
  • 增量备份还原完成
  • 重建 redo log,为启动数据库做准备,上述阶段叫做prepare 阶段
  • 将全量备份所在的临时目录文件,拷贝到 MySQL的数据目录中,修改权限

示意图如下: file


MySQL物理备份-Percona XtraBackup 备份/恢复原理
http://www.qiqios.cn/2021/08/16/mysql物理备份-percona-xtrabackup-备份-恢复原理/
作者
一亩三分地
发布于
2021年8月16日
许可协议