天天看點

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的有序性。

繼續閱讀