<p>必须开启binlog且格式为ROW:SHOW VARIABLES LIKE 'log_bin'返回ON,SHOW VARIABLES LIKE 'binlog_format'为ROW;同时确认binlog_row_image=FULL、过期时间足够,并用mysqlbinlog加--base64-output=DECODE-ROWS -v及时间范围解析日志,提取### SET值生成INSERT语句恢复,GTID模式下需--skip-gtids导出并避免直接在生产库执行。</p>

确认binlog是否开启且格式为ROW
没开binlog或格式是STATEMENT,后续所有操作都白搭。先连上MySQL执行:
SHOW VARIABLES LIKE 'log_bin';
返回ON才说明开启;再查:
SHOW VARIABLES LIKE 'binlog_format';
必须是ROW,MIXED或STATEMENT无法还原被删行的原始值。顺手确认一下:
-
binlog_row_image建议为FULL(默认值),否则可能只记录部分字段 -
expire_logs_days或binlog_expire_logs_seconds要大于误删发生距今的天数,否则文件已被自动清理 - 用
SHOW BINARY LOGS;看当前有哪些文件,结合误删时间判断日志是否还在
用mysqlbinlog定位误删事务位置
直接读二进制文件会看到乱码,必须用mysqlbinlog工具解析。关键参数有三个:
-
--base64-output=DECODE-ROWS:强制解码ROW事件,否则###开头的伪SQL看不到 -
-v(或--verbose):显示详细字段名和值,包括### SET @1=... @2=...这类变量赋值 -
--start-datetime和--stop-datetime:按业务日志/监控确认的误删时间范围过滤,避免翻几百MB日志
例如:
mysqlbinlog --base64-output=DECODE-ROWS -v --start-datetime="2026-10-14 13:20:00" --stop-datetime="2026-10-14 13:25:00" /var/lib/mysql/mysql-bin.000012 > /tmp/del_events.sql
输出里找DELETE FROM `db_name`.`table_name`,再看它前面的### DELETE FROM块——每个###行对应一行被删数据,### SET后面就是原始字段值。
从ROW事件反向生成INSERT语句
不能直接执行mysqlbinlog输出的SQL,里面含SET @@SESSION.GTID_NEXT等上下文,会破坏GTID模式或报错。正确做法是提取数据行,手动或脚本转成INSERT:
- 每一组
### DELETE FROM+### SET @1=... @2=...对应一条被删记录 - 注意
@1对应第一列,@2第二列……顺序与表结构一致,但不包含自增主键(除非显式插入) -
NULL值在日志中写作NULL,字符串带单引号,时间戳如'2026-10-14 13:22:01',需保留原时区 - 如果表有自增主键,INSERT时需显式指定该值,否则新插入会分配新ID,破坏一致性
示例片段(原始日志):
### DELETE FROM `test`.`users` ### WHERE ### @1=1001 ### @2='alice' ### @3='alice@example.com'
应转为:
INSERT INTO `test`.`users` (id, name, email) VALUES (1001, 'alice', 'alice@example.com');
GTID模式下跳过误删事务重放
如果实例启用了gtid_mode = ON,就不能用--start-position截断重放,否则会触发GTID_EXECUTED冲突或Cannot replicate because the master purged required binary logs错误。稳妥做法是:
- 先用
mysqlbinlog --skip-gtids导出不含GTID头的SQL(仅用于恢复,不用于复制) - 把误删事务前的所有事件重放到一个临时库,验证数据正确性
- 再把反向生成的
INSERT语句导入目标库,或用mysqldump导出后替换内容 - 切记:不要在原生产库上直接执行恢复SQL,避免写入新binlog覆盖现场
最易忽略的一点:binlog_rows_query_log_events = ON虽非必需,但开启后日志里会附带原始SQL(如# INSERT INTO ...),能快速确认哪条业务语句触发了批量删除——这对追查人为误操作非常关键。


















