binlog_row_image=full导致体积暴涨,因每次变更均记录所有列的前后镜像,尤其含text/blob时更甚;minimal仅存主键+实际修改列;noblob跳过所有大变长字段而非仅blob/text;切换需重启mysql并重建复制。

binlog_row_image=FULL 时,为什么 binlog 体积暴涨?
因为 FULL 模式下,MySQL 在每一行变更的 binlog event 中,会完整记录修改前(before image)和修改后(after image)所有列的值,哪怕只有 1 个字段变了,其他 99 个字段也全写进去。尤其当表里有 TEXT、BLOB 或长 VARCHAR 字段时,binlog 文件会迅速膨胀。
- 典型场景:频繁更新大文本字段的评论表、日志表
- 影响:磁盘 I/O 增加、主从同步延迟变高、备份恢复时间拉长
- 注意:
FULL是 MySQL 5.6.2+ 默认值,但不是“最安全”的默认——它只是兼容性最强
MINIMAL 模式下,UPDATE/DELETE 事件少了哪些字段?
MINIMAL 只保留能唯一定位行 + 实际变更的最小列集:主键或唯一非空索引列(用于定位),加上真正被修改的列(用于重放)。没改的字段、非唯一索引列、NULL 值列(除非被显式设为 NULL)一律不记。
- 常见错误现象:从库报
Could not execute Update_rows event on table ...; Can't find record in 'xxx'—— 往往是主键缺失或唯一索引失效,导致 MINIMAL 定位失败 - 使用前提:必须有有效主键或唯一非空索引,否则退化为 FULL 行为(但不报错)
- 性能收益明显:对宽表小更新场景,binlog 体积常能减少 40%~70%
NOBLOB 和 FULL 的 binlog 差异只在 BLOB/TEXT 字段?
不是。虽然名字叫 NOBLOB,但它实际跳过的不只是 BLOB 和 TEXT 类型字段,还包括所有长度可变且可能很大的类型,比如 MEDIUMTEXT、LONGTEXT、TINYBLOB 等。其余字段行为等同于 FULL。
- 容易踩的坑:以为设了
NOBLOB就能省空间,结果表里全是VARCHAR(8000)—— 这些仍会被完整记录 - 兼容性风险:如果下游消费者(如 Canal、Debezium)依赖完整字段做解析,
NOBLOB可能导致字段值为空或解析失败 - 注意:
NOBLOB在 MySQL 5.6.2+ 可用,但 8.0.23+ 已标记为 deprecated,未来版本会移除
如何安全切换 binlog_row_image 参数?
不能直接改全局变量就完事。MySQL 要求该参数在 server 启动时确定,运行中修改仅对新连接生效,且已建立的复制通道不会自动重载,必须重建才能生效。
- 正确步骤:停写、修改
my.cnf中的binlog_row_image、重启 MySQL、重置并重新配置主从复制(CHANGE MASTER TO ...) - 切到
MINIMAL前务必确认:所有业务表都有主键;无主键表必须先补主键,否则复制会出错 - 线上环境建议先在从库上验证:开启
log_slave_updates,观察 binlog 内容是否可被正常解析和重放
真正麻烦的从来不是参数本身,而是你表结构里那些没主键的旧表、下游解析器对字段缺失的容忍度、以及重启复制时那一分钟的写入中断窗口。










