Mysql 主從複製-Binlog詳細解析(Row格式)
阿新 • • 發佈:2019-01-04
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的長度,後面緊跟著資料
有需求或是什麼不懂得地方,歡迎交流。