溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

解析MYSQL BINLOG 二進(jìn)制格式(1)--準(zhǔn)備工作

發(fā)布時(shí)間:2020-08-10 16:35:14 來(lái)源:ITPUB博客 閱讀:183 作者:gaopengtttt 欄目:MySQL數(shù)據(jù)庫(kù)
原創(chuàng):轉(zhuǎn)載請(qǐng)說(shuō)明出處謝謝!

參考源:
1、源碼log_event.h log_event.cc pack.c
2、internals-en.epub


一、目的
   本系列文件主要為了說(shuō)明
1、為什么說(shuō)row格式較statement更占空間
2、為什么說(shuō)row格式的binlog更加安全
3、INSERT/UPDATE/DELETE是生成的row binlog如何直接看懂二進(jìn)制格式
4、DDL生成的binlog是怎么樣的
5、INSERT SELECT/CREATE TABLE 如何生成的row binlog

二、使用版本和數(shù)字顯示
本系列文章重要解釋MYSQL 5.6后row格式的binlog格式以及和事物有關(guān)的event,按照官方的說(shuō)法
binlog的格式經(jīng)歷了幾個(gè)階段
v1:mysql 3.23
v3:mysql 4.0.2 到 4.1
v4:mysql 5.0以上
v2版本只是短暫的存在過(guò),當(dāng)然我們要解析當(dāng)然是v4版本的binlog
因?yàn)橐词?.6以上的binlog
關(guān)于多字節(jié)的數(shù)字顯示,一般使用 Little-endian模式,做到和OS系統(tǒng)無(wú)關(guān),除非刻意說(shuō)明
關(guān)于Little-endian參考:
http://blog.itpub.net/7728585/viewspace-2124159/
三、binlog的魔法數(shù)
關(guān)于MYSQL BINLOG的作用就不做過(guò)多的解析了,在binlog中存儲(chǔ)的是一種稱(chēng)之為event的條目,
它們以二進(jìn)制的格式存儲(chǔ),平時(shí)我們使用的mysqlbinlog工具也就是對(duì)這種二進(jìn)制格式的文件
進(jìn)行解析,得到直觀(guān)的輸出。這里不用mysqlbinlog而改為直接看二進(jìn)制文件,當(dāng)然我會(huì)對(duì)比
MYSQLBINLOG的輸出和二進(jìn)制解析的過(guò)程
每一個(gè)binlog文件都有4字節(jié)的魔法數(shù),其值固定為
[root@testmy mysqld.1]# hexdump -Cv test.000005 
可以看到
fe 62 69 6e .bin

四、binlog event的總體構(gòu)架
一個(gè)event包括了
event header
event data
其中event data又分為
fixed data(posted header)
variable data

event header:全部的event統(tǒng)一固定的格式
fixed data(posted header):每一類(lèi)event固定
variable data:就是可以變化實(shí)際值了

關(guān)于event的類(lèi)型比較多詳細(xì)參考末尾源碼的截取

五、本系列文章要討論的event
而這里我們只要討論5.6,5.7中和row binlog格式和innodb
聯(lián)系比較緊密的幾種event如下:
query_log_event/QUERY_EVENT typecode=02
Format_description_log_event/FORMAT_DESCRIPTION_EVENT  typecode=15
Xid_log_event/XID_EVENT  typecode=16
Table_map_log_event/TABLE_MAP_EVENT typecode=19
Write_rows_log_event/WRITE_ROW_EVENT typecode=30
Update_rows_log_event/UPDATE_ROW_EVENT typecode=31 
Delele_rows_log_event/DELETE_ROW_EVENT typecode=32 

因?yàn)檫@些語(yǔ)句是一個(gè)事物必須經(jīng)歷的,而Format_description_log_event是一個(gè)最重要的
說(shuō)明性的event

六、通用頭文件(event header)解析
下面先解釋一下通用的19個(gè)字節(jié)。
每一個(gè)event有一個(gè)固定的頭信息叫做event header:
event header
timestamp        0:4             
type_code        4:1  
server_id           5:4
event_length     9:4
next_position    13:4
flags                 17:2             


timestamp:固定4字節(jié)展示是新紀(jì)元(epoch time)以來(lái)的秒數(shù)
type_code:固定1字節(jié)event事件的編碼,在源碼中是一個(gè)enum類(lèi)型負(fù)載最后源碼處
server_id:固定4字節(jié)就是 show variables like '%server_id';出來(lái)的值
event_length:固定4字節(jié)整個(gè)event的長(zhǎng)度,包含固定和非固定長(zhǎng)度
next_position:固定4字節(jié)下一個(gè)event的開(kāi)始位置(2^32為4G)
flags:固定2字節(jié) event flags
      LOG_EVENT_BINLOG_IN_USE_F   0x1 這個(gè)flags表示是否binlog正確的關(guān)閉了,這個(gè)標(biāo)示只出現(xiàn)在Format_description_log_event中
      LOG_EVENT_THREAD_SPECIFIC_F 0x4 是否查詢(xún)基于了臨時(shí)表,如果基于了臨時(shí)表MYSQLBINLOG必須設(shè)置 @@PSEUDO_THREAD_ID=xx
      LOG_EVENT_SUPPRESS_USE_F    0x8 和--binlog-do-db 、 --replicated-do-db有關(guān)
      其他還有很多
      LOG_EVENT_ARTIFICIAL_F 0x20 LOG_EVENT_RELAY_LOG_F 0x40 LOG_EVENT_IGNORABLE_F 0x80 LOG_EVENT_NO_FILTER_F 0x100 。。。
      可以自行參考log_event.h源碼頭文件中的詳細(xì)解釋
      
七、packed interger
在binlog中部分?jǐn)?shù)字使用這種方式顯示,在后面的解析中會(huì)提到
按照文檔和源碼中的說(shuō)明
如果第一個(gè)字節(jié)為0-250及0X0-0XFA那么這個(gè)字節(jié)就是實(shí)際顯示的數(shù)字值
源碼的:
  if (length < (ulonglong) LL(251))
  {
    *packet=(uchar) length;
    return packet+1;
  }
如果第一個(gè)字節(jié)為252及0XFC那么后面的2個(gè)字節(jié)的值為0XFB-0XFFFF
源碼的:
if (length < (ulonglong) LL(65536))
  {
    *packet++=252;
    int2store(packet,(uint) length);
    return packet+2;
  }
如果第一個(gè)字節(jié)為253及0XFD那么后面的3個(gè)字節(jié)的值為0XFFFF-0XFFFFFF
源碼的:
if (length < (ulonglong) LL(16777216))
  {
    *packet++=253;
    int3store(packet,(ulong) length);
    return packet+3;
  }
如果第一個(gè)字節(jié)為254及0XFE那么后面的8個(gè)字節(jié)的值為0XFFFFFF-0XFFFFFFFFFFFFFFFF
  *packet++=254;
  int8store(packet,length);

可以自行參考源碼接口,函數(shù)返回值為一個(gè)下一個(gè)位置的指針
uchar *net_store_length(uchar *packet, ulonglong length)


點(diǎn)擊(此處)折疊或打開(kāi)

  1. enum Log_event_type
  2. {
  3.   /**
  4.     Every time you update this enum (when you add a type), you have to
  5.     fix Format_description_event::Format_description_event().
  6.   */
  7.   UNKNOWN_EVENT= 0,
  8.   START_EVENT_V3= 1,
  9.   QUERY_EVENT= 2,
  10.   STOP_EVENT= 3,
  11.   ROTATE_EVENT= 4,
  12.   INTVAR_EVENT= 5,
  13.   LOAD_EVENT= 6,
  14.   SLAVE_EVENT= 7,
  15.   CREATE_FILE_EVENT= 8,
  16.   APPEND_BLOCK_EVENT= 9,
  17.   EXEC_LOAD_EVENT= 10,
  18.   DELETE_FILE_EVENT= 11,
  19.   /**
  20.     NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
  21.     sql_ex, allowing multibyte TERMINATED BY etc; both types share the
  22.     same class (Load_event)
  23.   */
  24.   NEW_LOAD_EVENT= 12,
  25.   RAND_EVENT= 13,
  26.   USER_VAR_EVENT= 14,
  27.   FORMAT_DESCRIPTION_EVENT= 15,
  28.   XID_EVENT= 16,
  29.   BEGIN_LOAD_QUERY_EVENT= 17,
  30.   EXECUTE_LOAD_QUERY_EVENT= 18,

  31.   TABLE_MAP_EVENT = 19,

  32.   /**
  33.     The PRE_GA event numbers were used for 5.1.0 to 5.1.15 and are
  34.     therefore obsolete.
  35.    */
  36.   PRE_GA_WRITE_ROWS_EVENT = 20,
  37.   PRE_GA_UPDATE_ROWS_EVENT = 21,
  38.   PRE_GA_DELETE_ROWS_EVENT = 22,

  39.   /**
  40.     The V1 event numbers are used from 5.1.16 until mysql-trunk-xx
  41.   */
  42.   WRITE_ROWS_EVENT_V1 = 23,
  43.   UPDATE_ROWS_EVENT_V1 = 24,
  44.   DELETE_ROWS_EVENT_V1 = 25,

  45.   /**
  46.     Something out of the ordinary happened on the master
  47.    */
  48.   INCIDENT_EVENT= 26,

  49.   /**
  50.     Heartbeat event to be send by master at its idle time
  51.     to ensure master's online status to slave
  52.   */
  53.   HEARTBEAT_LOG_EVENT= 27,

  54.   /**
  55.     In some situations, it is necessary to send over ignorable
  56.     data to the slave: data that a slave can handle in case there
  57.     is code for handling it, but which can be ignored if it is not
  58.     recognized.
  59.   */
  60.   IGNORABLE_LOG_EVENT= 28,
  61.   ROWS_QUERY_LOG_EVENT= 29,

  62.   /** Version 2 of the Row events */
  63.   WRITE_ROWS_EVENT = 30,
  64.   UPDATE_ROWS_EVENT = 31,
  65.   DELETE_ROWS_EVENT = 32,

  66.   GTID_LOG_EVENT= 33,
  67.   ANONYMOUS_GTID_LOG_EVENT= 34,

  68.   PREVIOUS_GTIDS_LOG_EVENT= 35,

  69.   TRANSACTION_CONTEXT_EVENT= 36,

  70.   VIEW_CHANGE_EVENT= 37,

  71.   /* Prepared XA transaction terminal event similar to Xid */
  72.   XA_PREPARE_LOG_EVENT= 38,
  73.   /**
  74.     Add new events here - right above this
  75.     Existing events (except ENUM_END_EVENT) should never change their numbers
  76.   */
  77.   ENUM_END_EVENT /* end marker */
  78. };


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI