1. 程式人生 > >Mysql 主從複製-Binlog詳細解析(Row格式)

Mysql 主從複製-Binlog詳細解析(Row格式)

Mysql 主從複製過程中,資料交換主要是依託於mysql的Binlog,本文將對mysql的binlog進行詳細的解析,從二進位制來分析binlog的語義。

binlog又分為3中,statement格式,row格式,mixed格式。

statement 格式就是把所有資料變化的sql記錄下來,但是如果出現now() rand()等函式時,會造成主從不一致的情況。

mixed格式是將row和statement結合起來,DML用row,DDL用statement。

row格式是比較複雜的,下面會詳細介紹。

首先,我們先來做個測試,執行以下sql語句。

我們做了對於一個空的資料庫做了6個操作,其中,1和2為DDL,row格式不記錄。6為查詢語句,row格式也不記錄。重點分析中間的3條。

背景:

    Mysql binlog 採用小端儲存,fe 62 69 6a 應解析為 6a6962fe。

Mysql binlog的開頭。

在binlog中,所有改變都被記錄為event,每個event的前19個Byte為頭。頭的解析規則為:

  • fe 62 69 6e : 所有binlog的統一的頭
  • a6 77 0b 56 :1443592102 seconds from Linux epoch  #從1970年1月1日起到日誌記錄時的秒數
  • 0f          : type #日誌型別
  • 01 00 00 00 : server-id #mysql配置的server-id
  • 67 00 00 00 : Length103 #該event的資料長度
  • 6b 00 00 00 : Next Event Start Pos107 #下個event的其實位置
  • 01 00       : Flag #標誌位
  • 04 00       : Binlog-version # mysql-binlog的版本
  • 50個位元組    : mysql-server version #mysql的版本
  • a6 77 0b 56 : 1443592102 #時間戳

每個跟資料相關的event都會對應一個table_map event,table_map event的解析方式為:

Table_map event的頭和前面的分析方法一樣,除去頭,Table_map event 為:

  • 29 00 000000 00  : tablenumber #表的編號
  • 0100       : flag #標誌位
  • 06          : DBnamelength #資料庫名字的長度,後面緊跟著資料庫的名字,最後是一個 00 的分隔符
  • 06          : Tablenamelength#資料庫表名字的長度,後面緊跟著資料庫表的名字,最後是一個 00 的分隔符
  • 03          : Column number #資料庫表的列的數量
  • 03 0f 0f: Typeof column(03 MYSQL_TYPE_LONG) 資料庫表中列的型別

(0f MYSQL_TYPE_VARCHAR)

  • 04          : metadata length #資料庫表列的元資料長度
  • ff 00      : 255 varchar length #varchar型別的欄位長度為255
  • 07          : checksum #校驗位

insert,delete,update分別為有自己的格式,其中最複雜的是update,因為其記錄了變化之前的資料和變化以後的資料,下面以update的例:

update操作的頭同樣和前面的相同,這裡就不再分析了,略過頭後,二進位制表達的意義為:

  • 29 00 000000 00 : tablenumber #要update的表編號
  • 01 00       : flag #標誌位
  • 03          : Column number #列的數量
  • ff ff: Addition #附加位
  • f8          : int startpos #int型別起始標誌位
  • 01 00 00 00 : id = 1
  • 08          : length #下面varchar的長度,後面緊跟著資料

有需求或是什麼不懂得地方,歡迎交流。