天天看点

MySQL内核月报 2014.12-MySQL· 答疑释惑·binlog event有序性

<b>背景</b>

  对于解析mysql的binlog用来更新其他数据存储的应用来说,binlog的顺序标识是很重要的。比如根据时间戳得到binlog位点作为解析起点。

  但是binlog里面的事件,是否有稳定的有序性?

  binlog中有三个看上去可能有序的信息:xid、timestamp、gno。本文分析这三个信息在binlog中的有序性。

<b>xid</b>

  当binlog格式为row,且事务中更新的是事务引擎时,每个事务的结束位置都有xid,xid的类型为整型。

  mysql中每个语句都会被分配一个全局递增的query_id(重启会被重置),每个事务的xid来源于事务第一个语句的query_id。

  考虑一个简单的操作顺序:

  session 1: begin; select; update;

  session 2: begin; select; update; insert; commit;

  session 1: insert; commit;

  显然xid2 &gt; xid1,但因为事务2会先于事务1记录写binlog,因此在这个binlog中,会出现xid不是有序的情况。

<b>timestamp</b>

  时间戳的有序性可能是被误用最多的。在mysqlbinlog这个工具的输出结果中,每个事务起始有会输出一个set timestamp=n。这个值取自第一个更新事件的时间。上一节的例子中,timestamp2&gt;timestamp1,但因为事务2会先于事务1记录写binlog,因此在这个binlog中,会出现timestamp不是有序的情况。

<b>gno</b>

  对于打开了gtid_mode的实例,每个事务起始位置都会有一个gtid event,其内容输出格式为uuid:gn,gno是一个整型数。

  由于next_gtid是可以直接指定的,因此若故意构造,可以很容易得到不是递增的情况,这里只讨论automatic模式下的有序性。

  与上述两种情况不同,gno生成于事务提交时写binlog的时候。注意这里不是生成binlog,而是将binlog写入磁盘的时候。因此实现上确保了同一个uuid下gno的有序性。

<b>小结</b>

  一个binlog文件中的xid和timestamp无法保证有序性。在无特殊操作的情况下,相同的uuid可以保证gno的有序性。

继续阅读