一、什么是 XtraBackup?

Percona XtraBackup 是由 Percona 公司开发的一款开源 MySQL 物理热备份工具,专为 InnoDB/XtraDB 存储引擎设计。它能够在不停止数据库服务的情况下执行备份,是 MySQL DBA 进行数据库备份恢复的行业标准工具之一。

官网:http://www.percona.com/software/percona-xtrabackup

二、核心特性

  • 在线热备份:备份过程中数据库仍可正常读写,不影响业务连续性

  • 非阻塞备份:备份 InnoDB 表时不锁表,仅备份 MyISAM 等引擎时短暂锁定

  • 增量备份:仅备份自上次备份以来的变化数据,大幅节省存储空间

  • 快速恢复:通过 redo log 重放保证数据一致性,恢复速度远超逻辑备份

  • 压缩加密:支持备份数据的压缩和 AES 加密,提高安全性和存储效率

  • 流式备份:支持将备份直接传输到远程服务器或云存储(如 S3、Azure)

  • 备份校验:自动验证备份文件的完整性,确保备份可用

三、版本与MySQL对应关系

XtraBackup 版本

MySQL 版本

XtraBackup 2.4

MySQL 5.6 / 5.7

XtraBackup 8.0

MySQL 8.0

XtraBackup 8.1

MySQL 8.1

XtraBackup 8.4

MySQL 8.4

四、工具组成

  • xtrabackup:核心备份/恢复程序,支持全量、增量、流式备份

  • xbstream:打包/解包工具,用于流式备份的打包处理

  • xbcrypt :加密/解密工具,用于备份数据的加解密

  • xbcloud:云存储上传工具,支持将备份直接上传到对象存储

  • xbcloud_osenv:xbcloud 的封装工具

五、备份原理

XtraBackup 的备份基于 InnoDB 的 redo log(事务日志) 机制:

  1. 记录起始 LSN:备份开始时记录当前日志序列号(Log Sequence Number)

  2. 复制数据文件:直接复制 InnoDB 数据文件(.ibd),此过程不锁表

  3. 监控 redo log:后台进程持续监控并记录备份期间产生的新事务

  4. 记录结束 LSN:备份结束时记录最终 LSN

  5. 保证一致性:恢复时通过重放 redo log,将数据恢复到备份完成时的一致状态

六、适用场景

场景

推荐理由

数据量 > 50GB

物理备份速度远快于 mysqldump 逻辑备份

7×24 业务

热备份不中断服务,保障业务连续性

需要增量备份

仅备份变化数据,节省存储和带宽

快速灾难恢复

恢复速度极快,可直接基于备份启动实例

云数据库备份

腾讯云、AWS 等云厂商广泛采用的标准备份方案

七、与mysqldump比较

对比项

XtraBackup

mysqldump

备份方式

物理备份(复制数据文件)

逻辑备份(导出 SQL)

备份速度

⚡ 极快

🐢 较慢

恢复速度

⚡ 极快

🐢 较慢

增量备份

✅ 支持

❌ 不支持

是否锁表

仅 MyISAM 短暂锁定

全库锁定(或一致性视图)

备份文件大小

较大(与数据文件相当)

较小(可压缩)

跨平台恢复

❌ 需版本/架构一致

✅ 可移植性强

单表恢复

较复杂

简单灵活

八、安装方式

注意:XtraBackup 版本必须与 MySQL 版本严格对应

yum安装

1、添加Percona YUM 仓库

yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

2、启用对应 MySQL 版本的仓库

percona-release setup ps80

3、安装 XtraBackup

yum install percona-xtrabackup-80

二进制安装

1、下载安装包

wget https://downloads.percona.com/downloads/Percona-XtraBackup-8.0/Percona-XtraBackup-8.0.35-30/binary/tarball/percona-xtrabackup-8.0.35-30-Linux-x86_64.glibc2.17.tar.gz

2、解压

tar -xvf percona-xtrabackup-8.0.35-30-Linux-x86_64.glibc2.17.tar.gz

3、查看版本

cd percona-xtrabackup-8.0.35-30-Linux-x86_64.glibc2.17/bin
./xtrabackup --version

九、备份与恢复

备份

全量备份

# 基本全量备份
xtrabackup --backup --target-dir=/data/backups/full --user=backup --password='backup_password'

# 完整示例
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --target-dir=/data/backups/full_$(date +%Y%m%d_%H%M%S) \
    --parallel=4 --compress

# 备份指定库
xtrabackup --backup --user=backup --password='backup_password' \
    --target-dir=/backup/test_db_full \
    --tables="^test_db[.].*"

# 指定库不备份
xtrabackup --backup --user=backup --password='backup_password' \
    --target-dir="/data/backups/full" \
    --databases-exclude='test'

# 指定表不备份
xtrabackup --backup --user=backup --password='backup_password' \
    --target-dir="/data/backups/full" \
    --tables-exclude='test\.tb_log.*|test\.tb_tmp.*'

核心参数:

  • --backup:标识执行备份操作

  • --target-dir:备份文件存放目录

  • --user/--password:数据库认证信息

  • --defaults-file:指定 MySQL 配置文件

  • --host/--port/--socket:连接方式

  • --parallel:指定使用多少个线程参与备份,如果10个CPU,一般设置为7左右。不指定就默认是单线程

  • --compress:不指定使用的压缩算法,默认就按照当前xtrabackup默认指定的压缩算法进行压缩(确保已安装压缩工具)

  • --compress-threads:默认是1,表示指定多少个线程来参与压缩,一般为CPU的70%左右

  • --databases-exclude:用于指定排除哪些数据库不备份

  • --tables-exclude:用于指定需要排除那些表不进行备份,支持正则和扩展正则

注意:进行全备份时,备份文件的大小和MySQL数据目录大小差不多一样大,并且备份过程中对硬盘I/O的要求比较高。

增量备份

# 1.先创建一个完整的备份
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --target-dir=/data/backups/full \
    --parallel=4 --compress

# 2.创建第一次增量备份
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --incremental-basedir="/data/backups/full" \
    --target-dir="/data/backups/incr_1" \
    --parallel=4 --compress

# 3.创建第二次增量备份
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --incremental-basedir="/data/backups/incr_1" \
    --target-dir="/data/backups/incr_2" \
    --parallel=4 --compress

# 4.创建第三次增量备份
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --incremental-basedir="/data/backups/incr_2" \
    --target-dir="/data/backups/incr_3" \
    --parallel=4 --compress

差异备份

# 差异备份:每次增量备份都基于全量备份增量备份。
# 1.先创建一个完整的备份
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --target-dir=/data/backups/full \
    --parallel=4 --compress

# 2.每次基于全备份做增量备份
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --incremental-basedir="/data/backups/full" \
    --target-dir="/data/backups/diff_1" \
    --parallel=4 --compress

# 3.每次基于全备份做增量备份
xtrabackup --host=192.168.2.100 --port=3306 --user=backup --password='backup_password' \
    --backup --defaults-file=/etc/my.cnf \
    --incremental-basedir="/data/backups/full" \
    --target-dir="/data/backups/diff_2" \
    --parallel=4 --compress

恢复

全备份恢复

# 1.停止MySQL服务,并备份数据目录
systemctl stop mysqld.service 
mv /var/lib/mysql  /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown -R mysql:mysql /var/lib/mysql

# 2.全备份预处理
xtrabackup --prepare --parallel=4 --use-memory=4G --target-dir="/data/backups/full"

# 3.拷贝备份数据到MySQL数据目录
xtrabackup --copy-back --parallel=4 --target-dir="/data/backups/full" --datadir="/var/lib/mysql"
chown -R mysql:mysql /var/lib/mysql

# 4.重启MySQL服务
systemctl restart mysqld.service

增量备份恢复

# 1.停止MySQL服务,并备份数据目录
systemctl stop mysqld.service 
mv /var/lib/mysql  /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown -R mysql:mysql /var/lib/mysql

# 2.全备份预处理
xtrabackup --prepare --apply-log-only --parallel=4 --use-memory=4G --target-dir="/data/backups/full"

# 3.将第一个增量备份数据合并到全备份数据中
xtrabackup --prepare --apply-log-only --parallel=4 --use-memory=4G \
    --target-dir="/data/backups/full" --incremental-dir="/data/backups/incr_1"
    
# 4.将第二个增量备份数据合并到全备份数据中
xtrabackup --prepare --apply-log-only --parallel=4 --use-memory=4G \
    --target-dir="/data/backups/full" --incremental-dir="/data/backups/incr_2"

# 5.将第N个增量备份合并到全备份数据中(最后一个增量合并不加--apply-log-only)
xtrabackup --prepare --parallel=4 --use-memory=4G \
    --target-dir="/data/backups/full" --incremental-dir="/data/backups/incr_N"

# 6.拷贝备份数据到MySQL数据目录
xtrabackup --copy-back --parallel=4 --target-dir="/data/backups/full" --datadir="/var/lib/mysql"
chown -R mysql:mysql /var/lib/mysql

# 7.重启MySQL服务
systemctl restart mysqld.service

差异备份恢复

# 1.停止MySQL服务,并备份数据目录
systemctl stop mysqld.service 
mv /var/lib/mysql  /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown -R mysql:mysql /var/lib/mysql

# 2.全备份预处理
xtrabackup --prepare --apply-log-only --parallel=4 --use-memory=4G --target-dir="/data/backups/full"

# 3.将差异备份数据合并到全备份数据中
xtrabackup --prepare --apply-log-only --parallel=4 --use-memory=4G \
    --target-dir="/data/backups/full" --incremental-dir="/data/backups/diff_1"

# 4.全备份预处理
xtrabackup --prepare --parallel=4 --use-memory=4G --target-dir="/data/backups/full"

# 5.拷贝备份数据到MySQL数据目录
xtrabackup --copy-back --parallel=4 --target-dir="/data/backups/full" --datadir="/var/lib/mysql"
chown -R mysql:mysql /var/lib/mysql

# 6.重启MySQL服务
systemctl restart mysqld.service

压缩后的全备份恢复

# 1.停止MySQL服务,并备份数据目录
systemctl stop mysqld.service 
mv /var/lib/mysql  /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown -R mysql:mysql /var/lib/mysql

# 2.将压缩后的全备份数据进行解压(确保已安装压缩工具)
xtrabackup --decompress --parallel=4 --target-dir="/data/backups/full"

# 3.全备份预处理
xtrabackup --prepare --parallel=4 --use-memory=4G --target-dir="/data/backups/full"

# 4.拷贝备份数据到MySQL数据目录
xtrabackup --copy-back --parallel=4 --target-dir="/data/backups/full" --datadir="/var/lib/mysql"
chown -R mysql:mysql /var/lib/mysql

# 5.重启MySQL服务
systemctl restart mysqld.service

物理备份是通过直接拷贝 MySQL 数据目录下的文件实现,而逻辑备份可以通过开启事务来确保数据的一致性,但物理备份在备份过程中无法避免数据的并发写入。
假设执行数据备份时,若有新的数据写入 MySQL,某些数据的元信息可能已记录到系统表中,但其数据部分可能尚未完全写入到数据文件中。这就导致了备份的文件里面记录了不完整的数据或未进行完成的事务。如果直接用这些数据去恢复MySQL,会导致数据损坏或一致性错误。
所以进行预处理( prepare 阶段)的作用就是回滚未提交的事务,丢弃不完整的数据,应用未完成的事务。这样就可以保证MySQL的数据文件和元数据信息对的上,才能确保恢复后的数据文件完整、可靠,并能够成功启动 MySQL。

核心参数:

  • --prepare:表示对备份的数据进行预处理操作

  • --use-memory:增加用于恢复操作的内存大小,通过这个选项可以加速恢复过程

  • --copy-back:将备份数据复制到mysql数据目录

  • --move-back:将备份数据移动到mysql数据目录,此时备份文件就没了

  • --decompress:会自动选择压缩时的算法,然后调用系统上的工具来进行解压

  • --incremental-dir:指定的就是存放增量备份数据的目录

  • --target-dir:指定的就是全备份数据的目录

  • --apply-log-only:默认未执行完的事务在 prepare 操作时会被回滚,通过这个参数可以不回滚这些事务,等待所有增备数据都合并了,再进行一次彻底的回滚(最后一个增量合并不加--apply-log-only)

十、备份脚本

XtraBackup-to-backup.sh

参考文章:https://www.cnblogs.com/hahaha111122222/p/18668742