mysql增量恢复必须同时满足四个条件:log_bin真正启用(show variables like 'log_bin'返回on)、server_id非零、binlog_format=row、全量备份带--master-data=2记录起始位置;缺一不可。

MySQL没有“开启binlog就能直接增量恢复”这回事——必须同时满足配置、权限、格式、起点记录四个条件,缺一不可。
确认 log_bin 真正生效,不是只改了配置
很多人改完 my.cnf 就以为成了,结果 SHOW VARIABLES LIKE 'log_bin' 还是 OFF。常见原因:
-
log-bin写成了log_bin(配置项名是log-bin,不是下划线) - 配置写在了
[client]或其他错误 section 下,必须在[mysqld]段内 - MySQL 进程没重启,或重启失败(检查
systemctl status mysqld) - 路径权限不对:
log-bin = /var/lib/mysql/mysql-bin要求该目录属主是mysql用户,且有写权限;用ls -ld /var/lib/mysql确认 - Docker 部署时挂载卷覆盖了 binlog 目录,
docker exec -it mysql ls -l /var/lib/mysql/mysql-bin.*才算真实存在
验证命令必须都成功:
SHOW VARIABLES LIKE 'log_bin'; -- 返回 ON<br>SHOW VARIABLES LIKE 'log_bin_basename'; -- 看到实际路径<br>SHOW BINARY LOGS; -- 至少列出一个文件,比如 mysql-bin.000001
必须设 server_id 且 binlog_format=ROW
server_id 不只是主从才需要——哪怕单机,不设非零值,某些 MySQL 版本会静默跳过写 binlog。而 binlog_format 必须为 ROW 或 MIXED:
-
STATEMENT格式在NOW()、UUID()、自增主键等场景下无法精确回放,恢复可能出错 - MySQL 5.7.7+ 默认是
ROW,但旧实例或手动改过配置的很可能还是STATEMENT,务必查SHOW VARIABLES LIKE 'binlog_format' -
ROW模式下,mysqlbinlog -v --base64-output=decode-rows才能看清具体哪一行被删/改,否则只能看到模糊事件
全量备份必须带 MASTER_LOG_POS 记录
增量恢复不是从“任意时间点”开始,而是从“上一次全量备份那一刻”开始追日志。所以全备不能用普通 mysqldump database,必须加:
mysqldump --single-transaction --master-data=2 -u root -p mydb > full_$(date +%F).sql
这个命令会在 SQL 文件头部插入类似注释:
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000012', MASTER_LOG_POS=154;
这就是你后续用 mysqlbinlog 的起点。漏掉 --master-data=2,你就失去了锚点,所有“增量”都无从谈起。
恢复时别信 --stop-datetime,优先用 --stop-position
系统时钟漂移、跨时区、日志写入延迟都会让时间定位不准。更可靠的做法是:
- 先用
SHOW BINLOG EVENTS IN 'mysql-bin.000012' FROM 154 LIMIT 20找到误操作前最后一个end_log_pos - 再用
mysqlbinlog --start-position=154 --stop-position=2891 mysql-bin.000012 | mysql -u root -p - 如果跨多个文件(比如从
.000012到.000013),按顺序拼接:mysqlbinlog mysql-bin.000012 mysql-bin.000013 | mysql -u root -p,不能只选中间某一段 -
-d mydb可过滤库级 DML,但对DROP DATABASE或CREATE TABLE无效——DDL 是全局事件,必须靠位置精准截断
最易被忽略的一点:恢复前必须停写业务,或确保全量备份后没人执行过 FLUSH LOGS 或 RESET MASTER,否则 binlog 文件序号和位置就断了。











