【文檔】六、Mysql Binlog版本

binlog文件格式有以下幾種:
- v1:用於3.23版本
- v3:用於4.0.2到4.1版本
- v4:用於5.0及以上版本

v2版本只在4.0.x版本中使用,目前已經不再支持了。

處理binlog的程序必須支持以上所有的版本。這部分描述了服務器是如何區分所有的格式的,以便辨別binlog使用的版本。mysqlbinlog也是使用的相同的規則。

重要的常量:
- START_EVENT_V3=1
- FORMAT_DESCRIPTION_EVENT=15
- EVENT_TYPE_OFFSET=4
- EVENT_LEN_OFFSET=9
- ST_SERVER_VAR_LEN=50

binlog文件以一個4字節的魔法數開頭,後面跟着一個初始的描述事件,標誌文件的格式。
- 在v1和v3中,這個事件被稱爲開始事件(start event)
- 在v4中,被稱爲格式描述事件(format description event)

各個版本中,描述事件的頭和數據部分如下:

v1開始事件(69字節)

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    | = START_EVENT_V3 = 1
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    | = 69
+=====================================+
| event  | binlog_version   13 : 2    | = 1
| data   +----------------------------+
|        | server_version   15 : 50   |
|        +----------------------------+
|        | create_timestamp 65 : 4    |
+=====================================+

v3開始事件(75字節)

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    | = START_EVENT_V3 = 1
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    | = 75
|        +----------------------------+
|        | next_position    13 : 4    |
|        +----------------------------+
|        | flags            17 : 2    |
+=====================================+
| event  | binlog_version   19 : 2    | = 3
| data   +----------------------------+
|        | server_version   21 : 50   |
|        +----------------------------+
|        | create_timestamp 71 : 4    |
+=====================================+

v4格式描述事件(大於等於91字節,大小=76+事件類型的數字)

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    | = FORMAT_DESCRIPTION_EVENT = 15
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    | >= 91
|        +----------------------------+
|        | next_position    13 : 4    |
|        +----------------------------+
|        | flags            17 : 2    |
+=====================================+
| event  | binlog_version   19 : 2    | = 4
| data   +----------------------------+
|        | server_version   21 : 50   |
|        +----------------------------+
|        | create_timestamp 71 : 4    |
|        +----------------------------+
|        | header_length    75 : 1    |
|        +----------------------------+
|        | post-header      76 : n    | = array of n bytes, one byte per event
|        | lengths for all            |   type that the server knows about
|        | event types                |
+=====================================+

在所有的binlog版本中,描述事件的數據部分包含的部分相同字段:
- binlog_version

binlog版本數字(1、3或4)

  • server_version

服務器版本,字符串

  • create_timestamp

創建時間戳,如果不等於0,等於事件創建的秒數;這表示binlog文件穿件的時間。這個字段實際上沒有值,如果不爲零,也是重複的,因爲與頭中的timestamp一樣。

注意:這個字段是爲將來使用的,程序不應該依賴於這個值。這個值將來可能有其他的用處。

v4版本的格式描述事件數據中包含兩個額外的字段,以便解析其他類型的事件:
- header_length:事件頭的長度。這個值包含extra_headers字段,所以這個頭的長度19不包含extra字段。
- post-header lengths:每個事件固定數據部分的長度。

決定binlog版本

給定任何binlog文件,這部分的信息描述瞭如何決定文件格式。幾個關於描述事件格式的重要點:
- v1的頭字段對於所有的格式通用。(v3和v4的頭也是以v1的頭字段開始的,新增了next_position和標誌位字段)
- v3和v4的頭包含相同的字段。v3和v4的數據部分不一樣,v4的數據部分允許在不改變頭的情況的擴展格式。
- 可以簡單的通過讀取binlog_version字段的兩個字節,來決定binlog的版本,如果不是因爲這個字段在v1和v3/v4的位置不一樣的話。因此,有必要通過文件的第一個事件是不是v1的開始事件來決定binlog版本。

爲了判斷binlog版本,通過下面的步驟:

  1. 這個文件以一個4字節的魔法數開頭。跳過他,獲取到文件中的第一個事件(大多數情況下,這個事件是開始事件或者格式描述事件)
  2. 通過第一個事件,讀取兩個值:

    • 事件的EVENT_TYPE_POSITION(4)位置的1字節的類型編碼
    • 事件中第EVENT_LEN_OFFSET(9)位置的4字節的事件長度的值
  3. 如果類型編碼不是START_EVENT_V3或者FORMAT_DESCRIPTION_EVENT,文件格式是v3

  4. 如果類型編碼是START_EVENT_V3(1),檢查事件長度。如果長度小於75,文件格式是v1,否則是v3。爲什麼是75?因爲這是v3開始事件的長度:

    • 頭(19字節)
    • binlog版本(2字節)
    • 服務器版本(ST_SERVER_VER_LEN=50字節)
    • 時間戳(4字節)

把這些加起來19+2+50+4=75。因此,如果事件長度小於75,就一定是v1版本。

  1. 如果類型編碼是FORMAT_DESCRIPTION_EVENT(15),文件格式是v4。

但是,有幾種特殊情況需要處理:

異常情況1:在4.0和4.1版本中,binlog的第一個事件可能不是開始事件。因爲服務器只會在它啓動後的第一個binlog文件中寫開始事件。對於其他的文件,服務器會在當前日誌文件的結尾處寫一個ROTATE_EVENT事件,這樣在下個文件的開頭就不會寫開始事件了。如果日誌文件的開頭不是START_EVENT_V3或者FORMAT_DESCRIPTION_EVENT,可以斷定是v3版本,因爲這隻會出現在4.0和4.1版本中,而這兩個版本的版本都是v3格式的。

異常情況2:在5.1和5.2版本的Mysql中,有些較早的版本用v4格式寫binlog文件,但是使用的時間號與現有的v4不一樣。因此,當讀取FDE時纔會發現是v4版本,這種情況下,還需要讀取在21位置出現的字符串,表示服務器版本。如果版本號在受影響版本的集合中,事件會重新編號爲v4。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章