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函数,如下。