全量备份需用mysqldump加--master-data=2和--single-transaction,记录binlog位置;增量靠归档binlog文件并用mysqlbinlog转换;恢复须按序重放且跳过危险语句;权限需单独备份mysql库。

全量备份用 mysqldump,但默认不包含 binlog 位置信息
直接跑 mysqldump --all-databases 得到的是某一时点的快照,恢复后无法知道该快照对应哪条 binlog,后续增量就断了。必须显式加 --master-data=2(或 =1)才能在 dump 文件开头写入 CHANGE MASTER TO 注释,记录当时的 File 和 Position。
实操建议:
-
--master-data=2更安全:生成的是带#的注释行,恢复时不会误执行;=1是可执行语句,容易在非预期场景触发主从切换 - 务必配合
--single-transaction(InnoDB 表)或--lock-all-tables(含 MyISAM),否则备份期间写入会导致数据不一致 - 不要用
--skip-lock-tables或省略锁参数——看似快,实际导出的库可能跨事务状态,恢复后主键冲突、外键断裂都算轻的
增量备份靠 mysqlbinlog 解析 binlog,不是“备份”而是“归档”
binlog 本身是服务端持续写入的日志文件,mysqlbinlog 只是把它读出来转成 SQL 或 base64 格式。真正的增量备份动作是:定期把新产生的 binlog 文件拷走(比如用 cp 或 rsync),再用 mysqlbinlog 转换为可读/可重放格式存档。
常见错误现象:
- 直接在生产库上运行
mysqlbinlog mysql-bin.000001 > backup.sql—— 如果 binlog 正在被写入,输出可能截断或损坏 - 没清空过期 binlog,磁盘爆满导致 MySQL 停写;或设置
expire_logs_days=0却忘了监控空间 - 恢复时用错起始位置:比如全量备份记录的是
mysql-bin.000005的12345,但增量脚本从12346开始,漏掉最后一条事务
恢复顺序不能错:mysqldump 先还原,再按序重放 mysqlbinlog 输出
全量备份恢复完,数据库状态停留在 dump 时刻;之后所有变更都在 binlog 里。必须严格按 binlog 文件名顺序 + position 顺序应用,跳过、颠倒、重复都会导致数据错乱。
使用场景注意点:
- 如果中间有
FLUSH LOGS或 MySQL 重启,binlog 文件会轮转,需确认mysql-bin.000005→mysql-bin.000006的衔接位置是否连续 -
mysqlbinlog --start-position=12345 mysql-bin.000005后,下一段必须从mysql-bin.000006的4(因为每个 binlog 文件头固定占 4 字节)开始,不是从 0 - 遇到
DROP DATABASE或RESET MASTER这类语句要人工跳过,否则整个恢复流程崩掉
mysqldump 和 mysqlbinlog 都不处理权限与用户表
默认 mysqldump --all-databases 不导出 mysql 库(除非显式加上 --databases mysql),而用户、权限、存储过程等元数据都在里面。同样,mysqlbinlog 也不会单独记录 GRANT 操作的原始语句,只记录执行后的效果。
所以:
- 需要权限备份时,单独跑一次
mysqldump --databases mysql --tables user db procs_priv - 如果用了
--skip-grant-tables启动过实例,或者手动改过mysql.user表,这些变更不会出现在 binlog 中(因为不走 SQL 接口) - Percona XtraBackup 等物理备份工具能完整复制
mysql库,但mysqldump+binlog组合天然缺这一环
SET sql_log_bin=0 导致某些 DML 没进日志。这两个点查起来费时间,但一开始记日志、做校验就能避开。











