--apply-log 不读取 my.cnf,仅按备份时源库的 innodb_log_file_size 生成 ib_logfile*;恢复前须先删旧日志、对齐配置,再执行 --copy-back,由 mysql 启动时按配置重建日志文件。

恢复前执行 --apply-log 会重写 ib_logfile* 大小,但不读取或同步 my.cnf 中的 innodb_log_file_size
Percona XtraBackup 的 --apply-log 过程本质是回放备份期间收集的 redo 日志(存于 xtrabackup_logfile),并把数据页刷到一致状态。它**不会启动 MySQL 实例**,因此完全不加载 my.cnf 配置。它生成的 ib_logfile0 和 ib_logfile1 大小,只取决于备份时源库当时的 innodb_log_file_size 值 —— 这个值被硬编码在备份元数据(xtrabackup_checkpoints)或日志文件头里,和你目标库当前配置无关。
所以常见现象是:
- 你在 A 服务器用
innodb_log_file_size = 128M备份,--apply-log后得到两个 128MB 的ib_logfile* - 恢复到 B 服务器,B 的
my.cnf却写着innodb_log_file_size = 512M - 启动时报错:
InnoDB: Error: log file ./ib_logfile0 is of different size
这不是 XtraBackup “做错了”,而是它按源库状态忠实还原 —— 它没法、也不该替你改目标库配置。
为什么不能跳过 --apply-log 直接 copy-back?
跳过 --apply-log 意味着你把处于“崩溃一致性”状态的数据文件直接扔进新实例 —— 此时数据页可能有部分更新未落盘、undo 未清理、redo 未回放。MySQL 启动时会尝试 crash recovery,但:
- 如果备份是增量或包含未提交事务,crash recovery 很可能失败或产生脏数据
- 某些版本(如 MySQL 8.0.30+)在检测到
ib_logfile*缺失或大小不匹配时,会拒绝进入 recovery 流程,直接报Plugin initialization aborted - 即使侥幸启动,后续 DML 可能触发断言失败或主从复制中断
简单说:--apply-log 是物理备份恢复的必经步骤,不是可选项,只是它不负责适配目标环境。
恢复前必须对齐 ib_logfile* 大小的实操顺序
正确做法不是“避免不一致”,而是“主动控制不一致发生的时间点”。关键在于:先让目标实例停稳、清空旧日志、再让 --apply-log 输出与目标配置匹配的文件。
- 确认目标 MySQL 已彻底停止:
systemctl stop mysqld,且ps aux | grep mysqld无残留进程 - 进入目标
datadir(用SELECT @@datadir;查),执行:rm ib_logfile*—— 注意是rm,不是mv;InnoDB 会扫描所有匹配ib_logfile*的文件名,哪怕叫ib_logfile0.bak也会触发校验失败 - 编辑
my.cnf,确保[mysqld]下有明确的innodb_log_file_size(例如innodb_log_file_size = 512M) - 执行
xtrabackup --apply-log --target-dir=/path/to/backup—— 此时它仍按源库大小生成日志文件,但没关系,下一步会覆盖 - 执行
xtrabackup --copy-back --target-dir=/path/to/backup,把数据文件拷过去 - 启动前再次确认:
ls -lh /var/lib/mysql/ib_logfile*应为空(因为上一步已删),MySQL 启动时会按my.cnf自动重建正确大小的ib_logfile0和ib_logfile1
容易被忽略的兼容性细节
不同版本 XtraBackup 对 --apply-log 行为略有差异,但核心逻辑一致。真正容易出问题的是混合使用场景:
- 用 XtraBackup 2.4 备份 MySQL 5.7,恢复到 MySQL 8.0 ——
ib_logfile格式虽兼容,但 8.0 默认启用innodb_redo_log_capacity,若未显式关闭,可能与旧版日志管理冲突 - 备份时启用了
innodb_log_files_in_group = 3,但目标库配置仍是默认的 2 —— 启动时 InnoDB 会严格检查数量,报错类似log file ./ib_logfile2 is of different size - 使用
--parallel参数加速--apply-log,但没关掉innodb_parallel_redo_enabled—— 某些旧内核下可能导致日志头写入不完整,后续启动校验失败
最稳妥的做法:恢复前,目标库的 my.cnf 必须和备份源库的 innodb_log_file_size 与 innodb_log_files_in_group 完全一致;若必须调整,就按“停库 → 删日志 → 改配置 → 启动”四步来,别指望 --apply-log 替你跨环境适配。











