该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
FORMAT_DESCRIPTION_EVENT
class:Query_log_event
event:QUERY_EVENT
event_code:02
参考源:
1、log_event.h 中关于class Query_log_event的解释
2、log_event.cc
3、internals-en.epub
文档和源码解释都为如果发生改变数据库的语句都会在这部分显示
Query_log_event is created for each query that modifies the
database, unless the query is logged row-based.
但是需要改考虑这里的修改,如果按照DDL和DML分,
DDL:我们知道BINLOG只是记录了语句就在这部分显示
DML:DML会记录这部分因为这里考虑为ROW-FORMAT格式的没有语句他更改记录在
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
事件中了。但是他会记录一个BEGIN如:
#170209 7:12:19 server id 93157 end_log_pos 585 CRC32 0x3e6c10f8 Query thread_id=2 exec_time=1 error_code=0
SET TIMESTAMP=1486595539/*!*/;
BEGIN
/*!*/;
及这里的
00000240 42 45 47 49 4e f8 10 6c 3e d3 a5 9b 58 13 e5 6b |BEGIN..l>...X..k|
1、fixed data part
4 bytes:一个用于指定线程id的值源码中叫做slave_proxy_id,主要用于
创建临时表的避免重复
4 bytes:语句的执行时间,单位秒
1 bytes:执行语句的默认数据库名字长度,源码解释为
The length of the name of the currently selected database
2 bytes:执行语句的错误码,如果是0就表示没有错误,主要用于一些无事物引擎比如MyISAM引擎一个语句
如insert select 执行了一部分的情况,当slave进行复制的时候检查这个错误码如果不相同则
停止复制,所有的错误码写到了mysqld_error.h 中可以自行参考
源码解释为:
Error code generated by the master. If the master fails, the
slave will fail with the same error code, except for the error
codes ER_DB_CREATE_EXISTS == 1007 and ER_DB_DROP_EXISTS == 1008.
2 bytes:variable data part中status_vars block的长度,详见variable data part
源码解释为:
The length of the status_vars block of the Body, in bytes
2、variable data part
var-size:status_vars block 可能存在多个叫做status variable的键值对中,每个
status variable包含一个1 bytes的variable值余下的具体值,关于各种的
具体值附在最后为源码注释截取,当然internals-en.epub也有一部分下面是
internals-en.epub中的部分:
Q_FLAGS_CODE=0:4 bytes,只在MYSQL 5.0写入,不考虑
Q_SQL_MODE_CODE=1:8 bytes,他是一个每一位代表SQL_MODE中的一个值,参考
最后源码的解释
Q_CATALOG_CODE=2:只在MYSQL 5.0.0到5.0.3使用不考虑
Q_AUTO_INCREMENT=3:2 bytes非负整数用于表示参数auto_increment_increment
和auto_increment_offset,这个只会在auto_increment大于
1的时候出现
Q_CHARSET_CODE=4:6 bytes用于表示character_set_client,collation_connection
和collation_server参数(totally 2+2+2=6 bytes)参考最后源码
解释
Q_TIME_ZONE_CODE=5:用于描述time zone信息
Q_CATALOG_NZ_CODE=6:用于描述catalog name,长度占用一个字节,随后这个值为std
Q_LC_TIME_NAMES_CODE=7:2 bytes 非负整数,只有当lc_time_names不设置为en_US的时候使用
Q_CHARSET_DATABASE_CODE=8:2 bytes 非负整数为collation_database系统变量,5.7源码解释
说这部分新版本不一定使用。
当然这里还有很多,详细参考后面给出的源码解释和internals-en.epub相关部分
var-size:数据库名字,以0X00结尾,既然0X00结尾那么其长度为数据库名字实际长度+1
源码描述为:
db_len+1 The currently selected database, as a null-terminated string.
var-size:这就是真正的语句,文档中说这个域的长度不固定,当然固定因为他是具体的语句
但是他的长度可以通过下面的计算方式得出:
总长度(event_header中)-event_header长度(v4为19)-fixed data part(13)-
status_vars block的长度 - 默认数据库名字长度 来得到因为这些定值
实际解析:
我使用了语句 create table testctas1 as select * from testcast,当然我是5.7关闭了GTID
不然这个语句会报错的
这样会发现这个语句在binlog中转变为2部分
1、create table DDL部分
2、DML部分
DML部分我们先不考虑,下面是CREATE TABLE DDL部分的解析
binlog的Query_log_event 二进制部分
--event header:
这部分不想过多解析,如果不懂看前面的文章,因为都是一样的简单解析
d3 a5 9b 58: timestamp,小端显示
02: event_type为02
e5 6b 01 00:service_id,小端显示0X016be5及十进制93157
mysql> show variables like '%server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 93157 |
+---------------+-------+
bd 00 00 00:event长度
c0 01 00 00:下一个event位置
00 00:flags
--fixed data part
02 00 00 00:slave_proxy_id小端显示0X00000002 这个和mysqlbinlog 解析的 thread_id=2以及SET @@session.pseudo_thread_id=2/*!*/;一致
01 00 00 00:执行时间小端显示0X00000001 这个和mysqlbinlog 解析的exec_time=1
04:默认数据库长度我的数据库名字为test当然长度也就是0X04也就是4
00 00:执行错误码,我这里没有错误全是0X00
1a 00:status_vars block及0X001a及26,如果仔细数一下后面的status_vars block的大小确实是26,其实我就是按照这个分割开的。
--variable data part
00 00 00 00 00 01 00 00 20 40 00 00 00 00 06 03
73 74 64 04 21 00 21 00 21 00 :
这部分是非常重要的status_vars block需要一个键值对一个解释
-00 00 00 00 00:为Q_FLAGS2_CODE,
文档上说它只在MYSQL 5.0中写入
键为00 值为00 00 00 00
-01 00 00 20 40 00 00 00 00:
为Q_SQL_MODE_CODE,
键为01 值为00 00 20 40 00 00 00 00 小端显示
为0X40200000则换算一下为1075838976
可以看到这个和MYSQLBINLOG解析的
SET @@session.sql_mode=1075838976/*!*/;
可以看到一致,关于这个也可以看看最后的
关于源码的Q_SQL_MODE_CODE解释
-06 03 73 74 64:为Q_CATALOG_NZ_CODE,
键值06 值为03 73 74 64,0X03为长度,0X73 0X74 0X64就是
std的ASCII
-04 21 00 21 00 21 00:为Q_CHARSET_CODE
键值04 值为21 00 21 00 21 00,这个都是0X0021 就是33
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
可以看到和MYSQLBINLOG解析一致
74 65 73 74 00:这部分是数据库的实际名字以0X00结尾0X74 0X65 0X73 0X74就是test的ASCII值
和MYSQLBINLOG解析的use `test`/*!*/; 一致
43 52 45 41 54 45 20 54 41 42 4c 45 20 60
74 65 73 74 63 74 61 73 31 60 20 28 0a 20 20 60
69 64 31 60 20 69 6e 74 28 31 31 29 20 44 45 46
41 55 4c 54 20 4e 55 4c 4c 2c 0a 20 20 60 69 64
32 60 20 69 6e 74 28 31 31 29 20 44 45 46 41 55
4c 54 20 4e 55 4c 4c 2c 0a 20 20 60 6e 61 6d 65
60 20 76 61 72 63 68 61 72 28 32 30 29 20 44 45
46 41 55 4c 54 20 4e 55 4c 4c 0a 29 :
这部分就是实际的语句的文本值里面全是ASCII二进制显示而已
后记:
Query_log_event 是binlog中的关键的EVENT,DDL记录了语句并且记录了很多关于语句的参数环境信息可以看看
use `test`/*!*/;
SET TIMESTAMP=1486595539/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
mysqlbinlog解析出来的这些大部分是不是都在本文提到过?
关于ROW_format的DML的Query_log_event虽然没有具体语句但是它确实存在,记录语句为BEGIN,这个在以后的文章中会在解析