全量+增量自动恢复必须分阶段校验、顺序执行并预留手动干预点,否则xtrabackup_checkpoints缺失或binlog断链将导致静默失败和数据丢失。

全量+增量自动恢复不能靠单个脚本一气呵成,必须分阶段校验、顺序执行、手动干预点留出口——否则遇到 xtrabackup_checkpoints 缺失或 mysql-bin.00000x 断链,脚本会静默失败,数据就彻底丢了。
恢复前必须确认的三件事
自动恢复不是“一键回滚”,而是把人脑判断逻辑固化进脚本。这三步漏掉任意一个,后续全白忙:
- 检查全量备份目录下是否存在可读的
xtrabackup_checkpoints(物理备份)或CHANGE MASTER TO行(mysqldump逻辑备份);没有它,就不知道该从哪个 binlog 文件、哪个 pos 开始增量 - 确认待恢复的 binlog 文件全部存在且未被
expire_logs_days清理——常见错误是脚本用ls /var/lib/mysql/mysql-bin.*列文件,但实际 MySQL 已 purge,mysqlbinlog直接报错Could not open log file - 验证目标 MySQL 实例已停止:
systemctl is-active mysqld必须返回inactive;若还在运行,mysqldump恢复会写脏数据,xtrabackup --copy-back会因文件占用失败
mysqldump 全量 + binlog 增量的恢复脚本关键逻辑
这是最常用、兼容性最好的组合,适合 MySQL 5.7/8.0,无需额外安装 XtraBackup。脚本核心不是“执行命令”,而是“按顺序做决策”:
- 从全量 SQL 文件中提取
MASTER_LOG_FILE和MASTER_LOG_POS:用sed -n 's/.*CHANGE MASTER TO MASTER_LOG_FILE=..\(.*\)., MASTER_LOG_POS=\([0-9]\+\).*/\1 \2/p' full_20260420.sql,结果存为变量BINLOG_FILE和START_POS - 按时间顺序排列增量 binlog 文件:
ls -t /backup/inc_*.binlog | head -n 20(避免通配符乱序),再用mysqlbinlog --base64-output=decode-rows -v确认每个文件结尾的end_log_pos是否连续 - 恢复时加
--force参数绕过重复主键错误,但必须配合grep -q "Duplicate entry"检查日志,一旦命中就中断并告警——这不是异常,是业务双写或误操作的信号
xtrabackup 物理恢复脚本必须绕开的坑
用 xtrabackup 恢复比 mysqldump 快一个数量级,但脚本容错更苛刻:
-
--prepare阶段必须显式指定--apply-log-only给所有增量备份(除最后一个),否则--copy-back会报Log block numbers mismatch - 全量和每个增量目录下都要有有效的
xtrabackup_checkpoints,脚本里不能只检查存在,得用awk '/backup_type/ {print $3}' xtrabackup_checkpoints确认值是full-backuped或incremental -
--copy-back前必须清空 MySQL 数据目录(rm -rf /var/lib/mysql/*),但不能删mysql系统库目录本身——删错会导致mysqld --initialize失败,脚本应跳过performance_schema、sys等只读库
自动化脚本里最容易被忽略的收尾动作
恢复完成不等于服务可用。以下操作必须嵌入脚本末尾,且任一失败就退出:
- 重启后检查
mysqladmin ping -u root -p$PASS是否返回mysqld is alive,超时 30 秒直接 exit 1 - 执行
SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql','sys','information_schema','performance_schema');,确认用户库表数量与备份前基本一致(允许 ±1,防 DDL 变更) - 记录恢复终点时间到
/backup/recover_timestamp.log,格式为2026-04-21T07:05:22Z,供后续审计或对比 binlog 结束点











