首页/数据/数据工程与 ETL 速查/binlog 三种格式:ROW/STATEMENT/MIXED
CDC 与同步53 条

binlog 三种格式:ROW/STATEMENT/MIXED

MySQL binlog 支持三种格式:STATEMENT 记 SQL 语句、ROW 记每行前后镜像、MIXED 按语句自动选择。CDC 必须使用 ROW,只有行级镜像才能稳定还原增删改数据;语句级日志里 NOW()、UUID() 等非确定函数会导致回放与解析不一致。

三种格式是什么

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 场景必须在实例级统一。

易错点

  • 只调整了当前会话的格式,其它连接的日志仍是语句级,采集到的事件时有时无
  • 用 MIXED 跑 CDC,遇到函数或存储过程写入时解析结果与源端数据不一致
  • 从语句格式切到行格式后未重新评估磁盘容量,日志量增长导致磁盘告警
  • 以为切换格式会重写历史日志,实际只在切换点之后生效,采集起点选错就会出现数据缺口

数据来源与参考

  • MySQL 8.0 Reference Manual: Binary Logging Formats
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌