<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 > xid1,但因為事務2會先于事務1記錄寫binlog,是以在這個binlog中,會出現xid不是有序的情況。
<b>timestamp</b>
時間戳的有序性可能是被誤用最多的。在mysqlbinlog這個工具的輸出結果中,每個事務起始有會輸出一個set timestamp=n。這個值取自第一個更新事件的時間。上一節的例子中,timestamp2>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的有序性。