MySQL Binlog文件格式解析

MySQL通过Binlog进行主从数据的复制,Binlog是一种二进制格式的文件,理解Binlog二进制格式能够帮助我们进一步理解MySQL的主从复制原理。本文将对Binlog文件格式进行分析。

本文涉及的源码版本和相关参数如下:

  • MySQL Server 5.7.19
  • binlog_format:ROW
  • binlog_row_image:FULL
一、Binlog文件Magic Number:

Binlog文件,前4个字节固定为一个Magic Number,十六进制值为fe62696e,如果一个文件其前4个字节不是这个Magic Number,那么就可以认为其不是一个有效的Binlog文件。

二、Binlog event:

Binlog文件除了最前面的4个字节之外,就是一个一个的event,event包含两个部分,event header和event data。通常event header大小固定,event data大小可变。

event整体结构如下:

+===================+
| event header |
+===================+
| event data  |
+===================+

event header 和 event data 详细结构如下:

| ** event header ** |
| timestamp 0 : 4 |
| type_code 4 : 1 |
| server_id 5 : 4 |
| event_length 9 : 4 |
| next_position 13 : 4 |
| flags 17 : 2 |
| extra_headers 19 : x-19 |

| ** event data **| 
| fixed part x : y |
| variable part |

event header 结构解析:

  • timestamp:时间戳,表示该event的生成时间,占用4个字节
  • type_code:event类型,占用1个字节
  • server_id:生成event的server_id,占用4个字节
  • event_length:event的大小,占用4个字节
  • next_position:下一个event的位置,占用4个字节
  • flags:event flags,占用2个字节
  • extra_headers:额外的信息,占用的字节不确定,也可能没有。由event type为FORMAT_DESCRIPTION_EVENT 类型的event中的数据决定。

event data结构解析:

  • fixed part:固定的部分,每一种类型的event,其fixed part部分占用的大小是固定的。具体大小由类型为 FORMAT_DESCRIPTION_EVENT 的event中的可变数组的值决定。
  • variable part:可变的部分,这部分大小可变,具体由 event header 中的event_length 减去 event header 的大小 和 fixed part 部分的大小 获得。
三、FORMAT_DESCRIPTION_EVENT:

前面提到类型为FORMAT_DESCRIPTION_EVENT的event,这个event比较特殊,通常一个Binlog文件只有一个该类型的event,并且是Binlog文件中出现的第一个event。这个event存储着非常关键的元数据。

FORMAT_DESCRIPTION_EVENT类型的event,其event header固定为19个字节,没有extra_headers部分。其event data部分,只包含fixed part, 没有variable part部分。

fixed part部分如下:

  • binlog 版本信息:占用2个字节
  • mysql server 版本信息:占用50个字节
  • timestamp 时间戳:占用4个字节
  • header length:event header长度,占用1个字节,如果为19,表示所有类型的event,其event header的extra_headers部分都为空。
  • 可变的数组,每个元素占用一个字节,数组大小与event类型数量相同,每个元素表示该类型的event data 固定部分(fixed part)占用的大小。

通过FORMAT_DESCRIPTION_EVENT event中的header length和可变的数组,就可以确定每个类型的event header大小和fixed part部分的大小。从而为解析每个类型的event打下了基础。

四、event 类型汇总:

分析源码文件 libbinlogevents/include/binlog_event.h 中的枚举类型 Log_event_type,获取所有的event类型如下,一共40个,并不是所有的类型都会使用,有一些只是兼容之前的版本。

  • UNKNOWN_EVENT= 0,
  • START_EVENT_V3= 1,
  • QUERY_EVENT= 2,
  • STOP_EVENT= 3,
  • ROTATE_EVENT= 4,
  • INTVAR_EVENT= 5,
  • LOAD_EVENT= 6,
  • SLAVE_EVENT= 7,
  • CREATE_FILE_EVENT= 8,
  • APPEND_BLOCK_EVENT= 9,
  • EXEC_LOAD_EVENT= 10,
  • DELETE_FILE_EVENT= 11,
  • NEW_LOAD_EVENT= 12,
  • RAND_EVENT= 13,
  • USER_VAR_EVENT= 14,
  • FORMAT_DESCRIPTION_EVENT= 15,
  • XID_EVENT= 16,
  • BEGIN_LOAD_QUERY_EVENT= 17,
  • EXECUTE_LOAD_QUERY_EVENT= 18,
  • TABLE_MAP_EVENT = 19,
  • PRE_GA_WRITE_ROWS_EVENT = 20,
  • PRE_GA_UPDATE_ROWS_EVENT = 21,
  • PRE_GA_DELETE_ROWS_EVENT = 22,
  • WRITE_ROWS_EVENT_V1 = 23,
  • UPDATE_ROWS_EVENT_V1 = 24,
  • DELETE_ROWS_EVENT_V1 = 25,
  • INCIDENT_EVENT= 26,
  • HEARTBEAT_LOG_EVENT= 27,
  • IGNORABLE_LOG_EVENT= 28,
  • ROWS_QUERY_LOG_EVENT= 29,
  • WRITE_ROWS_EVENT = 30,
  • UPDATE_ROWS_EVENT = 31,
  • DELETE_ROWS_EVENT = 32,
  • GTID_LOG_EVENT= 33,
  • ANONYMOUS_GTID_LOG_EVENT= 34,
  • PREVIOUS_GTIDS_LOG_EVENT= 35,
  • TRANSACTION_CONTEXT_EVENT= 36,
  • VIEW_CHANGE_EVENT= 37,
  • XA_PREPARE_LOG_EVENT= 38,
  • ENUM_END_EVENT

基本上每种类型的event,其格式各不相同,必须针对每一种类型的event进行解析,MySQL源码中也是不同的event都有其对应的c++类进行解析。

发表评论