MySQL57Binlog文件格式解析

MySQL通过Binlog进行主从数据的复制,Binlog是一种二进制格式的文件,理解Binlog二进制格式能够帮助我们进一步理解MySQL的主从复制原理。本文将对Binlog文件格式进行分析,涉及的源码版本和相关参数如下:

MySQLServer5.7.19binlog_format:ROWbinlog_row_image:FULLBinlog文件头:

Binlog文件,前4个字节固定为一个MagicNumber,十六进制值为fee。

Binlogevent:

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

event结构如下:

eventheader结构:

eventheader结构解析:

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

fixedpart:固定的部分,每一种类型的event,其fixedpart部分占用的大小是固定的。具体大小由类型为FORMAT_DESCRIPTION_EVENT的event中的可变数组的值决定。variablepart:可变的部分,这部分大小可变,具体由eventheader中的event_length减去eventheader的大小和fixedpart部分的大小获得。FORMAT_DESCRIPTION_EVENT:

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

FORMAT_DESCRIPTION_EVENT类型的event,其eventheader固定为19个字节,没有extra_headers部分。其eventdata部分,只包含fixedpart,没有variablepart部分。

fixedpart部分如下:

binlog版本信息:占用2个字节mysqlserver版本信息:占用50个字节timestamp时间戳:占用4个字节headerlength:eventheader长度,占用1个字节,如果为19,表示所有类型的event,其eventheader的extra_headers部分都为空。可变的数组,每个元素占用一个字节,数组大小与event类型数量相同,每个元素表示该类型的eventdata固定部分(fixedpart)占用的大小。通过FORMAT_DESCRIPTION_EVENTevent中的headerlength和可变的数组,就可以确定每个类型的eventheader大小和fixedpart部分的大小。从而为解析每个类型的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++类进行解析。了解一种文件格式最好的方式,就是尝试用另外一种语言去解析它。后续将会对常用类型的event格式进行分析,并尝试使用Python语言将其解析出来,欢迎


转载请注明:http://www.aierlanlan.com/rzdk/5321.html