binlog 记录格式

binlog 日志有三种格式,可以通过 binlog_format 参数指定。、

statement 格式

使用 statement 格式,记录的内容是 SQL 语句原文,比如执行一条 update T set update_time=now() where id=1,记录的内容如下。

row 格式 (默认)

使用 statement 格式,涉及到 update_time=now() 获取系统时间等函数,同步数据时会出现问题。

使用 row 格式,记录的内容不再是简单的 SQL 语句了,还包含操作的具体数据,记录内容如下。

row 格式记录的内容看不到详细信息,要通过 mysqlbinlog 工具解析出来。

update_time=now() 变成了具体的时间 update_time=1627112756247,条件后面的@1、@2、@3 都是该行数据第 1 ~3 个字段的原始值。

mixed 格式

row 格式虽好,但是会比较占用空间,恢复与同步时会更消耗 IO 资源,影响执行速度。

使用 mixed 格式,MySQL 会判断这条 SQL 语句是否可能引起数据不一致,如果是,就用 row 格式,否则就用 statement 格式。

补充

mixed 下 now 函数仍然采用原 SQL 语句原因

Binlog 设置的是 mixed 格式,在 SQL 中使用 now() 的时候,日志中的该句子仍然是 statement 格式。原因在于,binlog 日志内会记录语句当前的时间戳。见 MySQL Binlog 日志查看

statement 无法替代 row 格式的原因