MySQL增量备份必须依赖binlog而非mysqldump,需开启log-bin并正确配置,配合全备(如xtrabackup或mysqldump加--master-data=2)与binlog归档,恢复时先还原全备再按序重放对应binlog。

MySQL 增量备份依赖 binlog,不是 mysqldump 能解决的
mysqldump 默认是全量导出,不带增量能力。真正做增量备份,必须开启并正确配置 binlog,它是 MySQL 记录所有写操作(INSERT、UPDATE、DELETE、DROP 等)的二进制日志。没有开启 log-bin,就不存在“增量”这个概念。
检查是否启用:SHOW VARIABLES LIKE 'log_bin'; —— 返回 ON 才可继续。
常见疏漏点:
- 只在
my.cnf里加了log-bin=mysql-bin,但没重启 MySQL,配置未生效 - 磁盘空间不足导致
binlog自动停止写入(SHOW BINARY LOGS;查看实际存在哪些文件) - 设置了
expire_logs_days过小(如 1 天),旧 binlog 被自动清理,导致无法回溯到某次全备之后的全部变更
全备 + binlog 截断是标准增量方案
所谓“增量备份”,实际是定期做一次全量备份(如每天凌晨用 mysqldump 或 mysqlpump),再持续归档新生成的 binlog 文件。恢复时:先还原全备,再按顺序重放该时间点之后的所有 binlog。
关键操作步骤:
- 全备时加
--master-data=2(或--dump-slave=2如果是备库),让 dump 文件里自带CHANGE MASTER TO语句,记录备份时刻的binlog filename和position - 备份后立即执行
FLUSH BINARY LOGS;,让后续写入写入新文件,便于归档边界清晰 - 用
cp或rsync定期拷贝新增的binlog文件(如mysql-bin.000012)到备份目录,**不要用mysqlbinlog --read-from-remote-server实时拉取**——网络中断或权限问题会导致丢日志
mysqlbinlog 解析与重放有编码和 GTID 陷阱
直接用 mysqlbinlog 解析 binlog 再导入,看似简单,实则容易失败:
- 如果原库用了
utf8mb4,而mysqlbinlog默认以latin1解析,中文会乱码甚至报错 —— 必须加--base64-output=DECODE-ROWS -v(行模式)或显式指定--character-sets-dir - 开启
gtid_mode=ON后,不能靠 position 恢复,必须用SET GTID_NEXT='xxx';或用mysqlbinlog --skip-gtids导出(跳过原有 GTID,避免主键冲突) -
mysqlbinlog输出含SET @@SESSION.GTID_NEXT语句时,若目标实例已存在同 GTID,会报错ERROR 1840 (HY000)—— 此时需先RESET MASTER;(仅限测试环境)或用--exclude-gtids过滤
生产环境建议用 xtrabackup + binlog 组合
mysqldump 全备会锁表(即使加 --single-transaction,对 DDL 仍可能阻塞),而 Percona XtraBackup 支持真正的热备,且能自动生成备份时刻的 xtrabackup_binlog_info 文件,明确记录对应 binlog 位置。
实操要点:
- 全备命令示例:
xtrabackup --backup --target-dir=/data/backup/$(date +%F) - 备份完成后,立刻执行
mysql -e "FLUSH BINARY LOGS;",然后cp新增 binlog 到备份目录旁 - 恢复时:
xtrabackup --prepare→rsync回数据目录 → 启动 MySQL → 用mysqlbinlog从xtrabackup_binlog_info记录的位置开始重放
真正难的不是工具调用,而是 binlog 的生命周期管理:什么时候删旧日志、如何验证归档完整性、是否跨机房同步 binlog 文件——这些环节一出问题,增量链就断了。










