三种格式是什么
MySQL 的二进制日志支持三种记录格式:STATEMENT 记录原始 SQL 语句,日志体积小但依赖执行环境一致;ROW 记录每一行变更的前后镜像,体积大但内容确定;MIXED 由服务器按语句类型自动在两者之间切换,兼顾体积与确定性。
为什么 CDC 必须用 ROW
CDC 的目标是拿到「哪一行从什么值变成了什么值」,只有行镜像能直接提供。语句级日志里包含 NOW()、UUID()、随机数等非确定函数,回放或解析时结果与源端不一致;UPDATE 与 DELETE 的语句也无法直接还原出被影响行的具体内容。
三种格式对比
| 格式 | 记录内容 | 适用 | 注意 |
|---|---|---|---|
| ROW | 每行变更的前后镜像 | CDC、可靠复制 | 日志体积相对较大 |
| STATEMENT | 原始 SQL 语句 | 简单场景、日志体积小 | 非确定函数导致主从不一致,难以还原增删改 |
| MIXED | 按语句自动选择 | 兼顾体积的一般场景 | 对 CDC 不可靠,不应使用 |
基本信息
| 参数名 | binlog_format |
|---|---|
| 取值 | ROW / STATEMENT / MIXED |
| MySQL 8.0 | 默认 ROW,参数为动态全局变量,可在线修改 |
| 较新版本 | 8.4 起不再支持 STATEMENT 与 MIXED,行格式是唯一选择 |
| CDC 要求 | 实例级固定为 ROW,并纳入参数基线 |
典型使用场景
- 接入 CDC 前核查:确认实例与目标库表使用的都是行格式
- 搭建复制链路:行格式能保证从库数据与主库一致
- 评估日志体积:从语句改为行格式后日志量会明显增长,需要同步评估磁盘
- 参数基线管理:把格式纳入巡检项,防止被其它变更顺手改掉
- 排查主从不一致:确认差异是否由语句级日志中的非确定函数引起
查看与切换
查看与切换
-- 查看当前格式(全局与当前会话都可能存在不同取值)
SHOW VARIABLES LIKE 'binlog_format';
-- 实例级切换:需要相应管理权限;已存在的旧日志文件仍保持原格式
SET GLOBAL binlog_format = 'ROW';
-- 行镜像内容:FULL 保留前后完整镜像,MINIMAL 只记录被改动的列
SHOW VARIABLES LIKE 'binlog_row_image';格式切换不会改写历史日志:同一个文件序列里可能前半段是语句、后半段是行镜像。CDC 工具从切换点之后才可靠,接入时的起点应选在切换之后。
只改当前会话的格式不会影响其它连接:其它连接写入的日志依然是语句级,采集到的事件时有时无。CDC 场景必须在实例级统一。