本文主要是介绍MySQL binlog存储格式笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
完全参考:《24 | MySQL是怎么保证主备一致的?》
binlog 存储格式笔记
statement
binlog 里面记录的就是 SQL 语句的原文;
mysql> show binlog events in 'master.000001';
- 第一行 SET @@SESSION.GTID_NEXT='ANONYMOUS’你可以先忽略;
- 第二行是一个 BEGIN,跟第四行的 commit 对应,表示中间是一个事务;
- 第三行就是真实执行的语句了。可以看到,在真实执行的 delete 命令之前,还有一个“use ‘test’”命令。这条命令不是我们主动执行的,而是 MySQL 根据当前要操作的表所在的数据库,自行添加的。这样做可以保证日志传到备库去执行的时候,不论当前的工作线程在哪个库里,都能够正确地更新到 test 库的表 t。use 'test’命令之后的 delete 语句,就是我们输入的 SQL 原文了。可以看到,binlog“忠实”地记录了 SQL 命令,甚至连注释也一并记录了。
- 最后一行是一个 COMMIT。你可以看到里面写着 xid=61。xid就用redo关联binlog用的。
记录SQL语句的缺点:在备库上执行,可能因为和主库走的索引不同,而导致数据不一致;
row
binlog
的内容:
可以看到,与 statement
格式的 binlog
相比,前后的 BEGIN
和 COMMIT
是一样的。但是,row
格式的 binlog
里没有了 SQL 语句的原文,而是替换成了两个 event
:Table_map
和 Delete_rows
。
- Table_map event,用于说明接下来要操作的表是 test 库的表 t;
- Delete_rows event,用于定义删除的行为。
其实,我们通过上图 是看不到详细信息的,还需要借助 mysqlbinlog 工具,用下面这个命令解析和查看 binlog 中的内容。因为图 5 中的信息显示,这个事务的 binlog 是从 8900 这个位置开始的,所以可以用 start-position 参数来指定从这个位置的日志开始解析。
mysqlbinlog -vv data/master.000001 --start-position=8900;
- server id 1,表示这个事务是在 server_id=1 的这个库上执行的。
- 每个 event 都有 CRC32 的值,这是因为我把参数 binlog_checksum 设置成了 CRC32。
- Table_map event 跟在图 5 中看到的相同,显示了接下来要打开的表,map 到数字 226。现在我们这条 SQL 语句只操作了一张表,如果要操作多张表呢?每个表都有一个对应的 Table_map event、都会 map 到一个单独的数字,用于区分对不同表的操作。
- 我们在 mysqlbinlog 的命令中,使用了 -vv 参数是为了把内容都解析出来,所以从结果里面可以看到各个字段的值(比如,@1=4、 @2=4 这些值)。
- binlog_row_image 的默认配置是 FULL,因此 Delete_event 里面,包含了删掉的行的所有字段的值。如果把 binlog_row_image 设置为 MINIMAL,则只会记录必要的信息,在这个例子里,就是只会记录 id=4 这个信息。
- 最后的 Xid event,用于表示事务被正确地提交了。
你可以看到,当 binlog_format 使用 row 格式的时候,binlog 里面记录了真实删除行的主键 id,这样 binlog 传到备库去的时候,就肯定会删除 id=4 的行,不会有主备删除不同行的问题。
总结
statement模式下,会导致主备数据执行不一致,而row模式下,因为记录的是真实行的主键,所以可以保证主备数据一致。
这篇关于MySQL binlog存储格式笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!