深入理解MySQL主从原理
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.6 重点Event之UPDATE_EVENT和XID_EVENT

2.6.1 UPDATE_EVENT

1.UPDATE_EVENT的作用

UPDATE_EVENT是UPDATE语句生成的Event,主要用于记录UPDATE语句的before_image实际数据和after_image实际数据,其中还包含table_id、映像位图、字段数量、行数据位图等信息。

2.源码重要接口

主库

· 初始化构造函数:Update_rows_log_event::Update_rows_log_event(THD *thd_arg,TABLE tbl_arg,const Table_id& tid,bool is_transactional,const uchar extra_row_info)。

· 数据写入函数:Rows_log_event::do_add_row_data。

· 写入binlog cache函数:Rows_log_event::write_data_header,Rows_log_event::write_data_body。

从库

· 读取构造函数:Update_rows_log_event::Update_rows_log_event(const char *buf,uintevent_len,const Format_description_event *description_event)。

· 应用函数:Rows_log_event::do_apply_event。

3.主体格式

UPDATE_EVENT的格式更加复杂一些,因此使用了更加丰富的区域来区别,如图2-9所示。

其中,固定部分如下。

table_id:6字节。

Reserved:2字节,保留以后使用。

可变部分如下。

var_header_len:当前2字节,通常为0x02 00。

columns_width:字段个数。

columns_before_image:before_image为位图,最少1字节。这里主要表示在Event中是否需要记录全部的字段值,受到参数 binlog_row_image 的影响,后面将单独讨论。如果参数binlog_row_image设置为FULL,则记录为0xff。

columns_after_image:after_image为位图,最少1字节。这里主要表示在Event中是否需要记录全部的字段值,受到参数 binlog_row_image 的影响,后面将单独讨论。如果参数binlog_row_image设置为FULL,则记录为0xff。

图2-9

注意:下列部分分为before_image和after_image,参见图2-9。

row Bit-field:位图,最少1字节。这个数据是行数据自带的,也就是在构造Event的时候传入的。每位代表一个字段。如果字段有实际数据则为0,否则为1。

row real data:实际行数据。这是自带的,按照字段排序。

4.实例解析

我们进行如下操作:

使用解析语句如下。

结果如下。

87 00 00 00 00 00:table_id为十六进制值87、十进制值135。

01 00:保留。

02 00:固定为0x02 00。

03:字段个数。

ff:columns_before_image,如果参数binlog_row_image设置为FULL,则固定为0xff。

ff:columns_after_image,如果参数binlog_row_image设置为FULL,则固定为0xff。

before_image

f8:before_image的row Bit-field,二进制值11111000,代表3列都有实际的数据。

29 00 00 00:实际数据为41。

07 67 61 6f 70 65 6e 67:0x07可变长度类型varchar的长度为7字节,67 61 6f 70 65 6e 67为gaopeng字符串的ASCII编码。

05 00 00 00:实际数据为5。

after_image

f8:after_image的row Bit-field,二进制值11111000,代表3列都有实际的数据。

29 00 00 00:实际数据为41。

06 79 61 6e 6c 65 69:0x06可变长度类型varchar的长度为6字节,79 61 6e 6c 65 69为yanlei字符串的ASCII编码。

05 00 00 00:实际数据为5。

这部分分为before_image和after_image,需要特别注意。如果我们将 before_image 和after_image完全交换会发生什么呢?请大家思考一下。

注意,STMT_END_F是一个标记,用于说明本Event是本 DML 语句的最后一个 DML Event。可以参考THD::binlog_flush_pending_rows_event函数,如下。