前面幾節介紹了MySQL的基本同步協議,4.1是個重要的轉折,新版的在協議包資料格式方面,一般要設定CLIENT_PROTOCOL_41,並且按照設定此標誌位的格式序列化與反序列化。但是4.1畢竟比較舊了,我們這次關注5.6帶來的變化。

1. 對事件的完整性校驗

5.6預設是對事件做完整性校驗的,即每個事件包的最後4個位元組是校驗和,校驗和作為事件體的一部分,算在事件長度中。並且沒有在之前的包格式中定義出來,需要額外加進去。校驗和計算方法只採用CRC32,不排除在以後的版本中使用別的演算法。

從庫需要通知主庫“我知道事件的尾部是校驗和,並且希望你傳送校驗和給我”。這個操作需要在傳送COM_BINLOG_DUMP命令之前完成,否則伺服器傳送完一個事件之後(應該是個偽ROTATE事件,並且事件長度不包括校驗和的4個位元組)立即附帶一個ERROR包。文字欄位內容是:“Slave can not handle replication events with the checksum that master is configured to log”。

通知方法是:傳送一個COM_QUERY命令,內容是“SET @master_binlog_checksum= @@global.binlog_checksum”。在MySQL5.6.14的rpl_slave.cc Line 2154中,傳送過後還傳送了第二個COM_QUERY命令,內容是“SELECT @master_binlog_checksum”,查詢結果應該是“CRC32”。這說明主庫做了CRC校驗,並且主庫知道從庫能夠正確的解析完整性校驗結果。

2. 新增的事件、標誌位與ROW事件格式解析變化

新增事件:HEARTBEAT_EVENT、IGNORABLE_EVENT、ROWS_QUERY_EVENT、WRITE_ROWS_EVENTv2、UPDATE_ROWS_EVENTv2、DELETE_ROWS_EVENTv2、GTID_EVENT、ANONYMOUS_GTID_EVENT、PREVIOUS_GTID_EVENT。

新增標誌位:待總結。

ROW格式的三個修改事件(update、write、delete),5.6會選用v2格式。和以前的格式相比,多出了extra_data和extra_data_length兩個欄位。特殊的,長度欄位是2個位元組,這兩個位元組和extra_data的長度一起算到長度欄位中。

header:
  if post_header_len == 6 {
4                    table id
  } else {
6                    table id
  }
2                    flags
  if version == 2 {
2                    extra-data-length
string.var_len       extra-data
  }

body:
lenenc_int           number of columns
string.var_len       columns-present-bitmap1, length: (num of columns+7)/8
  if UPDATE_ROWS_EVENTv1 or v2 {
string.var_len       columns-present-bitmap2, length: (num of columns+7)/8
  }

rows:
string.var_len       nul-bitmap, length (bits set in `columns-present-bitmap1`+7)/8
string.var_len       value of each field as defined in table-map
  if UPDATE_ROWS_EVENTv1 or v2 {
string.var_len       nul-bitmap, length (bits set in `columns-present-bitmap2`+7)/8
string.var_len       value of each field as defined in table-map
  }
  ... repeat rows until event-end