必须开启binlog才能做MySQL实时增量备份,因其本质是重放binlog事件;需配置log_bin、binlog_format=ROW,并通过FLUSH TABLES WITH READ LOCK或--single-transaction+--master-data=2安全获取位点。

为什么必须开 binlog 才能做实时增量备份
MySQL 的实时增量备份本质就是重放 binlog 里的事件,没开 binlog 就像录像机没开机——再好的回放工具也找不到画面。它不是可选功能,而是增量备份的基础设施。
常见错误现象:mysqldump --single-transaction --master-data=2 看似能导出位置,但若 log_bin 关闭,SHOW MASTER STATUS 返回空,后续任何基于位点的追加都失效。
- 检查是否启用:
SELECT @@log_bin;返回1才算生效 - 配置文件中必须有
log_bin = /var/lib/mysql/mysql-bin(路径需可写,且不能是相对路径) - 重启 MySQL 后执行
SHOW BINARY LOGS;,能看到至少一个mysql-bin.000001文件才算真正跑起来 - 注意
skip_log_bin或启动时加--skip-log-bin会强制关闭,优先级高于配置文件
binlog_format 设成 ROW 还是 STATEMENT
增量备份依赖日志内容可精确还原,STATEMENT 格式在非确定性函数(如 NOW()、UUID()、自增主键插入)下会导致主从不一致,备份恢复后数据可能错位或丢失。
ROW 是唯一稳妥选择:它记录每行变更前后的镜像,和 SQL 执行逻辑解耦,兼容所有场景,包括 DDL 隐式事务、触发器、存储过程内部修改。
- 确认当前格式:
SELECT @@binlog_format; - 配置项写为
binlog_format = ROW,不要用MIXED—— 它自动降级到STATEMENT的行为不可控 - 已有库改格式不影响历史日志,但新事务立刻生效;应用层无需改动,但要注意
ROW日志体积通常比STATEMENT大 3–5 倍
如何安全轮转 binlog 避免磁盘打满
binlog 不自动清理,expire_logs_days 已被弃用,靠它容易误删正在使用的日志;真正可控的方式是结合 max_binlog_size 和手动 PURGE,且必须和备份任务联动。
典型翻车现场:定时脚本只执行 PURGE BINARY LOGS BEFORE '2024-06-01 00:00:00';,但备份工具还没来得及上传当天日志,直接删掉导致断点不可续。
- 设上限:
max_binlog_size = 1073741824(1GB),避免单个文件过大影响传输和解析 - 轮转后立刻记下最新文件名:
SHOW MASTER LOGS;最末行即当前活跃日志 - PURGE 前先确认备份已归档该文件:
PURGE BINARY LOGS TO 'mysql-bin.000123';(指定文件名比时间更精准) - 监控关键指标:
df -h /var/lib/mysql+ 检查ls -lt /var/lib/mysql/mysql-bin.* | head -20
备份脚本里怎么拿到可靠的 binlog 位点
用 mysqldump 做全量备份时,--master-data=2 写入的 CHANGE MASTER TO 注释只是快照时刻的位点,如果 dump 耗时长(比如大表 SELECT 锁表),实际日志已推进很远,直接拿这个位点接增量会丢数据。
真正可靠的做法是:先 FLUSH TABLES WITH READ LOCK,再 SHOW MASTER STATUS 记下位点,最后才 mysqldump。但锁表影响业务,所以生产环境更常用 --single-transaction + --master-data=2 组合,前提是引擎为 InnoDB 且无长事务。
- 检查长事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(timediff(now(), trx_started)) > 60; - dump 命令示例:
mysqldump --single-transaction --master-data=2 --all-databases > full.sql - 解析位点别手撕:用
head -n 30 full.sql | grep "CHANGE MASTER TO"提取File和Position字段值 - 位点只对下一个
mysqlbinlog解析起点有效,不能跨服务器复用
最易被忽略的一点:binlog 事件时间戳(event_time)和系统时间不同步时,按时间 PURGE 或定位会偏移;永远以 File+Position 为准,别信日志里的 # at 1234 行号——那是文件内偏移,不是全局位点。










