mysql增量备份必须先确认binlog已启用(show variables like 'log_bin'返回on)、路径权限合法、server-id非零;全量备份须用--flush-logs和--master-data=2记录起始位置;增量只需归档新binlog文件,无需转sql。

必须先确认二进制日志已启用且可读
增量备份本质是复用 mysql-bin.* 日志文件,如果 log-bin 未开启或权限不足,后续所有操作都无效。检查方式很简单:
- 登录 MySQL 执行
SHOW VARIABLES LIKE 'log_bin';,返回ON才算启用 - 确认日志路径可被备份脚本读取:
SHOW VARIABLES LIKE 'log_bin_basename';,常见值如/var/lib/mysql/mysql-bin - 若路径在
/home/mysql/mysql-bin这类非默认位置,需确保运行备份脚本的用户(如mysql或root)对该目录有读权限
常见错误是配置了 log-bin 但忘记设 server-id(MySQL 5.7+ 强制要求),导致服务启动失败或 binlog 实际未写入。
全量备份必须带 --flush-logs 和 --master-data=2
这是增量链能接上的关键。不加这两个参数,你无法准确定位“从哪条 binlog 开始追增量”。
-
--flush-logs:强制滚动到新 binlog 文件(如从mysql-bin.000005切到mysql-bin.000006),让后续增量只覆盖新变更 -
--master-data=2:在 dump 文件头部插入注释行,例如CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=154;,恢复时直接可用 - 务必搭配
--single-transaction(InnoDB)或--lock-all-tables(混合引擎),否则备份瞬间的数据状态可能不一致
反例:mysqldump -u backup -p db1 > full_20260903.sql 没带任何参数——这个文件无法作为任何增量备份的基点。
增量备份只需归档新生成的 binlog 文件,别用 mysqlbinlog 导出 SQL
很多教程教用 mysqlbinlog --start-datetime="2026-09-02 02:00:00" mysql-bin.000006 导出 SQL,这会把二进制日志转成大几倍的文本,完全违背“降存储成本”的初衷。
- 正确做法:定时(如每天凌晨)执行
mysql -e "FLUSH LOGS;",然后cp或rsync当前最新的 binlog 文件(如mysql-bin.000006)到备份目录 - 保留策略直接按文件名序号清理:比如只留最近 5 个 binlog 文件,用
ls -t /var/lib/mysql/mysql-bin.* | tail -n +6 | xargs rm -f - 压缩?没必要。binlog 是二进制格式,
gzip压缩率极低(通常
注意:FLUSH LOGS 会触发新文件生成,所以增量归档脚本必须在它之后执行,否则会漏掉最后一批变更。
crontab 定时逻辑要严格区分全量与增量时间点
全量和增量不能在同一分钟跑,也不能靠“猜”时间差。典型可靠节奏是:
- 每周日凌晨 2:00:执行全量备份脚本(含
--flush-logs),生成full_20260901.sql并记录当前 binlog 名 - 每天凌晨 2:10:执行增量脚本,
FLUSH LOGS后立即cp上一个周期的 binlog(即全量后到此刻前的所有mysql-bin.000xxx) - 每天凌晨 2:15:清理过期 binlog,例如只保留最近 7 天内生成的文件(通过
stat -c '%y' mysql-bin.* | cut -d' ' -f1提取日期判断)
最容易被忽略的是:mysql-bin.index 文件也要一并备份。它记录了所有 binlog 文件名顺序,恢复时 mysqlbinlog 依赖它自动拼接日志流。漏掉它,你就得手动写一堆 --position 参数。











