4、MySQL物理备份:XtraBackup安装与配置、全量备份与恢复、增量备份与恢复、流式备份与压缩

各位同行,今天我们来聊聊MySQL物理备份的利器——XtraBackup。说实话,我在金融行业摸爬滚打这么多年,见过太多因为备份方案没选好而翻车的案例。逻辑备份用mysqldump,小库还行,一旦数据量上了百G,那恢复速度简直让人抓狂。所以,物理备份才是生产环境的王道。

XtraBackup是Percona公司开源的物理备份工具。它最大的特点就是——热备。什么意思?就是数据库在跑着业务,你照样可以备份,不会锁表,不会影响读写。这一点,对于7x24小时的金融系统来说,太重要了。

核心原理一句话:XtraBackup通过拷贝物理数据文件,并利用redo log保证数据一致性。说白了,就是一边复制文件,一边记录变化,最后把两者合并成一个完整的时间点快照。

4.1 安装与配置

安装其实不复杂。我个人习惯用Percona官方仓库,这样升级也方便。以CentOS 7为例:

# 安装Percona仓库
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

# 启用工具库
percona-release enable-only tools release

# 安装XtraBackup 8.0(对应MySQL 8.0)
yum install percona-xtrabackup-80

嗯,这里要注意版本匹配。MySQL 5.7用XtraBackup 2.4,MySQL 8.0用XtraBackup 8.0。我曾经见过有人把版本搞混,备份出来的文件根本恢复不了,白白浪费了几个小时。

安装完后,验证一下:

xtrabackup --version

看到版本号输出,就说明装好了。配置方面,其实不需要额外做什么。XtraBackup会读取MySQL的配置文件,自动找到数据目录和日志文件位置。你只需要确保备份用户有足够的权限:

-- 创建备份用户
CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY 'your_password';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'bkpuser'@'localhost';
FLUSH PRIVILEGES;

小提示:权限里LOCK TABLESREPLICATION CLIENT是必须的。前者用于备份时获取一致性锁,后者用于获取binlog位置信息。少了任何一个,备份都会报错。

4.2 全量备份与恢复

全量备份是最基础的操作。说白了,就是把整个数据库的数据文件完整拷贝一份。命令很简单:

xtrabackup --backup \
  --target-dir=/data/backup/full_20240101 \
  --user=bkpuser \
  --password=your_password \
  --host=localhost

执行过程中,你会看到类似这样的输出:

[01] Copying ibdata1 to /data/backup/full_20240101/ibdata1
[01]        ...done
[01] Copying ./mydb/t1.ibd to /data/backup/full_20240101/mydb/t1.ibd
[01]        ...done
...
230102 10:30:45 completed OK!

看到completed OK!,就说明备份成功了。但注意,这时候的备份文件还不能直接用。因为拷贝过程中,数据文件可能处于不一致状态。我们需要做一次准备操作:

xtrabackup --prepare --target-dir=/data/backup/full_20240101

这个步骤会应用redo log,把数据文件恢复到一致状态。我在项目中遇到过有人忘了这一步,直接拿备份文件去恢复,结果MySQL启动报错,说数据损坏。嗯,这个坑我踩过,你们就别再踩了。

恢复时,先把原数据目录备份一下(以防万一),然后把备份文件拷贝回去:

# 停止MySQL
systemctl stop mysqld

# 备份原数据目录
mv /var/lib/mysql /var/lib/mysql_bak

# 创建新数据目录
mkdir /var/lib/mysql

# 恢复备份
xtrabackup --copy-back --target-dir=/data/backup/full_20240101

# 修改权限
chown -R mysql:mysql /var/lib/mysql

# 启动MySQL
systemctl start mysqld

警告:恢复前一定要确保原数据目录已备份或清空。--copy-back不会覆盖已有文件,如果目录非空,会报错退出。另外,恢复后记得检查/var/lib/mysql的属主,必须是mysql:mysql,否则MySQL启动时会报权限错误。

4.3 增量备份与恢复

全量备份虽然完整,但每天做一次全量,数据量大了之后,磁盘和网络都扛不住。这时候就需要增量备份了。增量备份只记录自上次备份以来发生变化的数据,说白了就是只备份“变动的部分”。

增量备份基于LSN(Log Sequence Number)。每次备份都会记录一个LSN范围,增量备份就是在这个范围内拷贝变化的页。

先做一次全量备份作为基础:

xtrabackup --backup \
  --target-dir=/data/backup/full_20240101 \
  --user=bkpuser \
  --password=your_password

然后做增量备份:

xtrabackup --backup \
  --target-dir=/data/backup/inc_20240102 \
  --incremental-basedir=/data/backup/full_20240101 \
  --user=bkpuser \
  --password=your_password

第二天再做一次增量,基于上一次增量:

xtrabackup --backup \
  --target-dir=/data/backup/inc_20240103 \
  --incremental-basedir=/data/backup/inc_20240102 \
  --user=bkpuser \
  --password=your_password

恢复时,需要先把所有增量合并到全量备份上。这个过程叫整合(apply)

# 先准备全量备份
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full_20240101

# 合并第一个增量
xtrabackup --prepare --apply-log-only \
  --target-dir=/data/backup/full_20240101 \
  --incremental-dir=/data/backup/inc_20240102

# 合并第二个增量
xtrabackup --prepare --apply-log-only \
  --target-dir=/data/backup/full_20240101 \
  --incremental-dir=/data/backup/inc_20240103

# 最后做一次完整的prepare(不指定--apply-log-only)
xtrabackup --prepare --target-dir=/data/backup/full_20240101

关键点:除了最后一次prepare,前面的都要加上--apply-log-only。这个参数告诉XtraBackup只应用redo log,不回滚未提交的事务。如果忘了加,那增量备份就白做了,数据会丢失。我曾经在凌晨3点恢复数据时犯过这个错,结果多花了2小时重新做。血的教训啊。

合并完成后,用--copy-back恢复到数据目录即可,和全量恢复一样。

4.4 流式备份与压缩

备份文件越来越大,磁盘空间是个问题。而且,如果要把备份传到远程服务器,网络带宽也是瓶颈。流式备份加压缩,就是解决这两个问题的。

流式备份,说白了就是把备份数据直接通过管道输出,而不是写到磁盘文件。你可以把它压缩,或者直接传到远程服务器。

最常用的组合是xbstreamgzip

xtrabackup --backup \
  --stream=xbstream \
  --user=bkpuser \
  --password=your_password \
  | gzip > /data/backup/full_20240101.stream.gz

恢复时,先解压,再解流:

# 解压并解流到目标目录
gunzip -c /data/backup/full_20240101.stream.gz \
  | xbstream -x -C /data/backup/full_20240101

# 然后做prepare
xtrabackup --prepare --target-dir=/data/backup/full_20240101

如果你想要更高的压缩率,可以用lz4zstd。我个人推荐zstd,压缩比和速度都比较均衡:

xtrabackup --backup \
  --stream=xbstream \
  --compress=zstd \
  --compress-threads=4 \
  --user=bkpuser \
  --password=your_password \
  > /data/backup/full_20240101.stream.zst

恢复时,需要先解压再解流:

# 解压
zstd -d /data/backup/full_20240101.stream.zst -o /data/backup/full_20240101.stream

# 解流
xbstream -x -C /data/backup/full_20240101 < /data/backup/full_20240101.stream

# prepare
xtrabackup --prepare --target-dir=/data/backup/full_20240101

经验之谈:压缩线程数建议设置为CPU核心数的一半。比如4核CPU,设2个压缩线程。设太多反而会因为争抢CPU导致性能下降。我在一台32核的机器上测试过,8个线程是最优的。

下面这张图,帮你理清XtraBackup的核心流程:

XtraBackup 核心流程 MySQL 运行实例 全量备份 (Full Backup) Prepare (应用Redo Log) Copy-Back 恢复数据 可选 增量备份 合并到全量 可选 流式+压缩 远程存储 图例: MySQL实例 全量备份 Prepare 恢复 增量备份 流式压缩

好了,以上就是XtraBackup的核心内容。从安装配置,到全量备份恢复,再到增量备份和流式压缩,每一步都有它的应用场景。金融系统对数据安全要求极高,备份方案必须可靠。我个人建议,全量备份每周一次,增量备份每天一次,流式压缩后传到异地存储。这样即使机房出问题,数据也能快速恢复。

记住一句话:备份不做,等于裸奔。做了备份不验证,等于半裸奔。每次备份完,一定要找个测试环境恢复验证一下。我见过太多人备份文件坏了都不知道,等到真出事了才发现——嗯,那场面,真的很难看。


专注资料整理