图解MySQL | [原理解析] XtraBackup 备份恢复时为什么要加 apply-log-only 参数?

本文深入探讨XtraBackup备份恢复时apply-log-only参数的重要性。若未正确设置,可能导致数据不一致。通过实例说明如何避免未完成事务的错误回滚,确保数据完整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

XtraBackup 在 MySQL 备份场景中被广泛使用,大家一定不陌生。我们也在之前的两篇文章中分享了其备份的原理。(详见 [原理解析] XtraBackup全量备份还原 & [原理解析] XtraBackup增量备份还原)本文想要描述的是 XtraBackup 恢复时参数 apply-log-only 的作用,不知道大家有没有注意到,这个参数如果不设置,可能会产生数据不一致的惨剧。

使用 XtraBackup 对数据库做备份,实际上就是拷贝 MySQL 的数据文件,为了保证备份数据的最终一致,也会同时拷贝备份过程中的 Redo log。

如图 1 所示,全备开始时,事务 2 尚未提交,Redo log 中仅有事务 2 的一部分数据(B->F),XtraBackup 于是将这一部分数据拷贝到全备文件中。

如图 2 所示,增备开始时,事务 2 已经提交,Redo log 中有了事务 2 的完整数据。XtraBackup 于是将事务 2 的后一部分数据拷贝了下来。

如图 3 所示,恢复时,首先恢复全备中的数据文件,然后回放全备中的 Redo log,回放过程中应用了一部分事务 2(B->F),如果没有设置 apply-log-only,XtraBackup 会在恢复最后一步应用 undo,将这一部分残缺的事务回滚(F->B),就此埋下了祸根。

如图 4 所示,后续恢复增备文件时,继续回放了事务 2 的后一部分(E->G A->H),导致最终的数据文件中丢失了事务 2 第一部分的数据(B->F),惨剧就发生了。

如图 5 所示,正确的做法应该是除了最后一个增备,所有的备份恢复都应该设置 apply-log-only 参数(only 指的就是只回放 redo log 阶段,跳过 undo 阶段),避免未完成事务的回滚。如图所示,此时全备恢复后的数据文件才是完整的(包含了B->F)。所有增备恢复完成后的数据也是完整的。

参考:
https://www.percona.com/doc/percona-xtrabackup/2.3/xtrabackup_bin/xbk_option_reference.html#cmdoption-xtrabackup-apply-log-only

### 正确使用 `xtrabackup` 的 `--prepare` 参数及相关选项 #### 背景说明 在使用 Percona XtraBackup 工具备份文件本身并不能直接用于数据库恢复。为了使备份能够正常工作,必须先对其进行预处理(Prepare)。这一过程会应用事务日志并确保数据一致性。 --- #### 使用 `--prepare` 参数的流程 1. **执行初始准备阶段** 在完成全量备份之后,需要运行一次带有 `--prepare` 和 `--apply-log` 选项的操作来准备好备份文件。此操作的主要目的是重放所有的未提交事务,并清理不一致的数据状态。 命令如下: ```bash xtrabackup --prepare --apply-log --target-dir=/path/to/backup/ ``` 如果仅需部分增量备份,则可以上 `--apply-log-only` 参数以防止重复应用完整的日志记录[^1]。 2. **多次增量备份的应用** 当存在多个增量备份,在最终还原之前,需要依次对每个增量备份进行准备工作。对于中间的增量备份,应始终附 `--apply-log-only` 参数,以免提前结束日志应用的过程。 示例命令: ```bash xtrabackup --prepare --apply-log-only --target-dir=/full_backup_dir/ --incremental-dir=/inc_backup_01/ xtrabackup --prepare --apply-log-only --target-dir=/full_backup_dir/ --incremental-dir=/inc_backup_02/ ... xtrabackup --prepare --target-dir=/full_backup_dir/ ``` 上述最后一条语句不再包含 `--apply-log-only`,因为这是整个链路中的最后一个步骤[^4]。 3. **注意事项** - 若尝试在一个已经经过 prepare 的目标目录上重新调用该功能,可能会收到警告提示:“This target seems to be already prepared.” 这是因为系统检测到当前路径下的日志已经被完全解析过了[^3]。 - 对于单个数据库或者特定表组的情况,可以通过额外设置参数 `--databases` 来限定范围。 --- #### 实际案例分析 假设有一个名为 `/home/xbackdata/mysql` 的完整备份位置,以下是具体实施方法: ```bash # 初步整理全部变更至基础层 xtrabackup --prepare --apply-log-only --target-dir=/home/xbackdata/mysql/ # 合并第一个增量更新包 xtrabackup --prepare --apply-log-only \ --target-dir=/home/xbackdata/mysql/ \ --incremental-dir=/home/xbackdata/inc1/ # 继续入第二个增量差异集 xtrabackup --prepare --apply-log-only \ --target-dir=/home/xbackdata/mysql/ \ --incremental-dir=/home/xbackdata/inc2/ # 完成整体合并后的最终确认 xtrabackup --prepare --target-dir=/home/xbackdata/mysql/ ``` 上述脚本展示了如何逐步将多级增量调整融入原始快照之中[^2]。 --- #### 数据恢复指南 一旦完成了所有必要的 Prepare 操作后,就可以把修复完毕的内容迁移到实际生产环境里去替换原有的实例资料夹内容。通常做法是从源地址拷贝覆盖掉原有 MySQL Data Directory 下面对应的部分结构体。 示例迁移指令可能看起来像这样子: ```bash rsync -avP /home/xbackdata/mysql/* /var/lib/mysql/ chown -R mysql:mysql /var/lib/mysql/ service mysqld restart ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值