bigywater.tech
MySQL / InnoDB · 95

Binlog Row Image

对一张宽表只改一个窄列,对比binlog_row_image设成FULL和MINIMAL时,真实的binlog事件大小差多少。

约36倍
MINIMAL相对FULL模式真实缩小的事件大小比例
46字节
只改1个int列,MINIMAL模式真实的事件大小

做的事:一张宽表,只改其中一个窄列,对比两种记录模式

代码CREATE TABLE wide_row (id INT PRIMARY KEY, a VARCHAR(200), b VARCHAR(200), c VARCHAR(200), d VARCHAR(200), e INT); INSERT INTO wide_row VALUES (1, REPEAT('a',200), REPEAT('b',200), REPEAT('c',200), REPEAT('d',200), 100); -- 只改e这一个int列 UPDATE wide_row SET e = 200 WHERE id=1;

验证:FULL模式,真实把4个没改的宽列也记了一遍

实测 · 本机mysqlbinlog真实输出(binlog_row_image=FULL,默认值)
# at 429
end_log_pos 2099   Update_rows: table id 91 ...

真实事件大小:2099 - 429 = 1670 字节

虽然这条UPDATE真实只改了e这一个int列,FULL模式下binlog真实还是把改动前后完整的一整行都记录了下来——包括那4个各200字节、内容压根没变的VARCHAR列,真实占用了1670字节。

验证:切到MINIMAL,同样的更新真实缩到46字节

代码SET GLOBAL binlog_row_image = 'MINIMAL'; -- 新连接生效后,同样跑一次UPDATE wide_row SET e = 300 WHERE id=1;
实测 · 本机mysqlbinlog真实输出
# at 429
end_log_pos 475   Update_rows: table id 91 ...

真实事件大小:475 - 429 = 46 字节   ← 真实缩小了约36倍
MINIMAL模式下,binlog真实只记录"定位这一行需要的最少信息"(通常是主键)加上"真正发生变化的列"——那4个没被这条UPDATE碰过的宽列,真实完全不会出现在这个事件里。46字节对1670字节,真实缩小了约36倍,这个比例在真实生产环境的宽表(几十个列,只改其中一两个)上会更加悬殊。代价是MINIMAL模式下的binlog真实丢失了"改动前完整是什么样"这份历史快照,如果需要基于binlog做完整的行级审计或者反查历史值,FULL模式(或者折中的NOBLOB,只在没有真正变化时省略大字段)可能更合适,选择真实是磁盘/网络开销和审计能力之间的权衡。

分步演示:同一次更新,两种row_image模式的真实事件大小

每一步都是本文上面用真实mysqlbinlog测量跑出来的原始结果。

改1个窄列,FULL和MINIMAL真实差了36倍
这一步新验证的记录模式

    本文用到的工具

    • 本机真实的复制实验环境,5列宽表(4个VARCHAR(200)+1个INT)
    • binlog_row_image(FULL/MINIMAL/NOBLOB) + mysqlbinlog真实测量事件大小
    京ICP备2026067502号-1京公网安备11010502063487号