不必须,但不加--base64-output=DECODE-ROWS就无法解析ROW格式的行级变更,导致看不到真实字段值、###伪SQL缺失或乱码,进而无法生成准确回滚语句。

mysqlbinlog 解析时必须加 --base64-output=DECODE-ROWS 吗?
不必须,但不加就看不到行级变更的原始数据,也就没法生成回滚语句。MySQL 5.6+ 默认以 base64 编码输出 ROW 格式事件,mysqlbinlog 不解码的话,你看到的是类似 ### UPDATE ... ### WHERE @1=1 的伪SQL,无法直接映射到真实字段值。
实际操作中,应始终加上:mysqlbinlog --base64-output=DECODE-ROWS --verbose binlog.000001
-
--verbose是关键:它把 ROW 事件转成可读的伪SQL(带###前缀),这是后续提取和反转的基础 - 缺
--base64-output=DECODE-ROWS会导致###行缺失或乱码,脚本解析直接失败 - 如果 binlog 是 STATEMENT 格式,该参数无影响,但生产环境几乎不用 STATEMENT,所以默认要加
如何定位并提取某个事务的所有事件(含 BEGIN/COMMIT)?
MySQL 的 binlog 里事务不是靠“事务ID”标记的,而是靠 GTID 或连续的 Query_log_event + Table_map_log_event + Write_rows_log_event 等组合构成一个逻辑单元。最可靠的方式是用 mysqlbinlog --base64-output=DECODE-ROWS --verbose 输出后,按 # at 位置 + 时间戳 + GTID(如有)三重锚定。
- 先查出目标事务的起始位置或 GTID:比如从
SHOW BINLOG EVENTS IN 'binlog.000001' FROM 12345找到对应Query事件的end_log_pos - 再用
mysqlbinlog --start-position=12345 --stop-position=18765 --base64-output=DECODE-ROWS --verbose binlog.000001精确截取 - 注意:一个事务可能跨多个 binlog 文件,需检查
Prev_gtid_log_event和GTID_LOG_EVENT是否连续 - 不要依赖
BEGIN/COMMIT文本——它们在 ROW 模式下根本不会出现在输出里,只有XA START或显式BEGIN语句才可见
从 ### UPDATE 伪SQL 自动生成回滚语句的关键规则
回滚不是简单把 UPDATE 改成 UPDATE ... SET col=val_old WHERE col=val_new,而要严格交换 SET 和 WHERE 子句中的字段值,并还原主键/唯一键条件。伪SQL 中的 ### 行顺序固定:### UPDATE db.tbl → ### WHERE @1=... @2=... → ### SET @1=... @2=...。
- 回滚
UPDATE:把WHERE行的变量值挪到SET,SET行的变量值挪到WHERE;字段名需根据Table_map_log_event中的列定义反查(不能硬编码@1对应id) - 回滚
DELETE:把WHERE行内容改成INSERT INTO tbl (...) VALUES (...),值来自原WHERE行 - 回滚
INSERT:只生成DELETE FROM tbl WHERE ...,条件来自原SET行 - 字段类型影响值格式:比如
@3='2024-01-01'是日期,@4=123是整数,回滚时不能加引号错配
为什么用 Python 脚本解析比 sed/awk 更靠谱?
因为 ### 行嵌套深、字段顺序不固定、NULL 值写成 @5=NULL、字符串含转义(如 @2='O\'Reilly'),正则一不留神就断行或漏匹配。sed 处理多行状态难,awk 难维护列映射关系。
- 核心逻辑必须缓存当前事务的
table_map事件,才能把@n映射到真实列名 - 遇到
### INSERT时,需记住它属于哪个表、哪些列非空、主键是哪几列——这些信息分散在前面的Table_map_log_event和Write_rows_log_event中 - 推荐用
mysqlbinlog --read-from-remote-server流式读取 + 逐行状态机解析,避免加载整个 binlog 到内存 - 现成工具如
binlog2sql可用,但它默认不生成回滚语句,需打补丁或改写其rollback模块
真正麻烦的不是生成单条回滚 SQL,而是确保 WHERE 条件能精确命中原记录——尤其当表无主键、或有触发器修改字段时,回滚可能误删/误更。这点常被忽略。


















