binlog的格式

3 分钟阅读 433 字 + 307 词
binlog是逻辑日志
binlog_format=statement 时,binlog 里面记录的就是 SQL 语句的原文 (相当于记录了逻辑操作)。你可以用
binlog 的格式改为 binlog_format=‘row’
可以看到,与 statement 格式的 binlog 相比,前后的 BEGIN 和 COMMIT 是一样的。但是,row 格式的 binlog 里没有了 SQL 语句的原文,而是替换成了两个 event: Table_map 和 Delete_rows。
  • Table_map event,用于说明接下来要操作的表是 test 库的表 t;
  • Delete_rows event,用于定义删除的行为。
当 binlog_format 使用 row 格式 的时候, binlog 里面记录了真实删除行的主键 id ,这样 binlog 传到备库去的时候,就肯定会删除 id=4 的行,不会有主备删除不同行的问题,记录了行数据最终被修改成什么样了,每行数据的变化结果都会被记录,比如执行批量update,更新多少行数据就会产生多少条记录。
为什么会有 mixed 格式的 binlog?
基于上面的信息,我们来讨论一个问题:为什么会有 mixed 这种 binlog 格式的存在场景?
推论过程是这样的:
  1. 因为有些 statement 格式的 binlog 可能会导致 主备不一致 ,所以要使用 row 格式。
  2. 但 row 格式的缺点是,很占空间。**比如你用一个 delete 语句删掉 10 万行数据,用 statement 的话就是一个 SQL 语句被记录到 binlog 中,占用几十个字节的空间。**但如果用 row 格式的 binlog, 就要把这 10 万条记录都写到 binlog 中。这样做,不仅会占用更大的空间,同时写 binlog 也要耗费 IO 资源,影响执行速度。
  3. 所以,MySQL 就取了个 折中 方案,也就是有了 mixed 格式的 binlog。mixed 格式的意思是, MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格式,否则就用 statement 格式。