MySQL binlog记录的所有操作实际上都有对应的事件类型的,譬如STATEMENT格式中的DML操作对应的是QUERY_EVENT类型,ROW格式下的DML操作对应的是ROWS_EVENT类型。

首先,看看源码中定义的事件类型

源码位置:mysql-5.7.14/libbinlogevents/include/binlog_event.h

enum Log_event_type
{
/**
Every time you update this enum (when you add a type), you have to
fix Format_description_event::Format_description_event().
*/
UNKNOWN_EVENT= ,
START_EVENT_V3= ,
QUERY_EVENT= ,
STOP_EVENT= ,
ROTATE_EVENT= ,
INTVAR_EVENT= ,
LOAD_EVENT= ,
SLAVE_EVENT= ,
CREATE_FILE_EVENT= ,
APPEND_BLOCK_EVENT= ,
EXEC_LOAD_EVENT= ,
DELETE_FILE_EVENT= ,
/**
NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
sql_ex, allowing multibyte TERMINATED BY etc; both types share the
same class (Load_event)
*/
NEW_LOAD_EVENT= ,
RAND_EVENT= ,
USER_VAR_EVENT= ,
FORMAT_DESCRIPTION_EVENT= ,
XID_EVENT= ,
BEGIN_LOAD_QUERY_EVENT= ,
EXECUTE_LOAD_QUERY_EVENT= , TABLE_MAP_EVENT = , /**
The PRE_GA event numbers were used for 5.1.0 to 5.1.15 and are
therefore obsolete.
*/
PRE_GA_WRITE_ROWS_EVENT = ,
PRE_GA_UPDATE_ROWS_EVENT = ,
PRE_GA_DELETE_ROWS_EVENT = , /**
The V1 event numbers are used from 5.1.16 until mysql-trunk-xx
*/
WRITE_ROWS_EVENT_V1 = ,
UPDATE_ROWS_EVENT_V1 = ,
DELETE_ROWS_EVENT_V1 = , /**
Something out of the ordinary happened on the master
*/
INCIDENT_EVENT= , /**
Heartbeat event to be send by master at its idle time
to ensure master's online status to slave
*/
HEARTBEAT_LOG_EVENT= , /**
In some situations, it is necessary to send over ignorable
data to the slave: data that a slave can handle in case there
is code for handling it, but which can be ignored if it is not
recognized.
*/
IGNORABLE_LOG_EVENT= ,
ROWS_QUERY_LOG_EVENT= , /** Version 2 of the Row events */
WRITE_ROWS_EVENT = ,
UPDATE_ROWS_EVENT = ,
DELETE_ROWS_EVENT = , GTID_LOG_EVENT= ,
ANONYMOUS_GTID_LOG_EVENT= , PREVIOUS_GTIDS_LOG_EVENT= , TRANSACTION_CONTEXT_EVENT= , VIEW_CHANGE_EVENT= , /* Prepared XA transaction terminal event similar to Xid */
XA_PREPARE_LOG_EVENT= ,
/**
Add new events here - right above this comment!
Existing events (except ENUM_END_EVENT) should never change their numbers
*/
ENUM_END_EVENT /* end marker */
};

实际上还是蛮多的,下面就挑几个重点的说一下

QUERY_EVENT

QUERY_EVENT以文本的形式来记录事务的操作。

QUERY_EVENT类型的事件通常在以下几种情况下使用:

1. 事务开始时,执行的BEGIN操作。

2. STATEMENT格式中的DML操作

3. ROW格式中的DDL操作

譬如:

mysql> show binlog events in 'mysql-bin.000021';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| mysql-bin.000021 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000021 | 120 | Query | 1 | 195 | BEGIN |
| mysql-bin.000021 | 195 | Query | 1 | 298 | insert into test.t1 values(1,'a') |
| mysql-bin.000021 | 298 | Xid | 1 | 329 | COMMIT /* xid=25 */ |
| mysql-bin.000021 | 329 | Query | 1 | 408 | BEGIN |
| mysql-bin.000021 | 408 | Query | 1 | 515 | use `test`; insert into test.t1 values(2,'b') |
| mysql-bin.000021 | 515 | Xid | 1 | 546 | COMMIT /* xid=33 */ |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+

FORMAT_DESCRIPTION_EVENT

FORMAT_DESCRIPTION_EVENT是binlog version 4中为了取代之前版本中的START_EVENT_V3事件而引入的。它是binlog文件中的第一个事件,而且,该事件只会在binlog中出现一次。MySQL根据FORMAT_DESCRIPTION_EVENT的定义来解析其它事件。

它通常指定了MySQL Server的版本,binlog的版本,该binlog文件的创建时间。

譬如:

# at
# :: server id end_log_pos CRC32 0x03010da1 Start: binlog v , server v 5.6.-log created ::
# Warning: this binlog is either in use or was not closed properly.
mysql> show binlog events in 'mysql-bin.000021';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| mysql-bin.000021 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
...

ROWS_EVENT

对于ROW格式的binlog,所有的DML语句都是记录在ROWS_EVENT中。

ROWS_EVENT分为三种:WRITE_ROWS_EVENT,UPDATE_ROWS_EVENT,DELETE_ROWS_EVENT,分别对应insert,update和delete操作。

对于insert操作,WRITE_ROWS_EVENT包含了要插入的数据

对于update操作,UPDATE_ROWS_EVENT不仅包含了修改后的数据,还包含了修改前的值。

对于delete操作,仅仅需要指定删除的主键(在没有主键的情况下,会给定所有列)

对于QUERY_EVENT事件,是以文本形式记录DML操作的。而对于ROWS_EVENT事件,并不是文本形式,所以在通过mysqlbinlog查看基于ROW格式的binlog时,需要指定-vv --base64-output=decode-rows。

譬如:

mysql> show binlog events in 'mysql-bin.000027';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000027 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000027 | 120 | Query | 1 | 188 | BEGIN |
| mysql-bin.000027 | 188 | Table_map | 1 | 236 | table_id: 80 (test.t1) |
| mysql-bin.000027 | 236 | Write_rows | 1 | 278 | table_id: 80 flags: STMT_END_F |
| mysql-bin.000027 | 278 | Xid | 1 | 309 | COMMIT /* xid=198 */ |
| mysql-bin.000027 | 309 | Query | 1 | 377 | BEGIN |
| mysql-bin.000027 | 377 | Table_map | 1 | 425 | table_id: 80 (test.t1) |
| mysql-bin.000027 | 425 | Update_rows | 1 | 475 | table_id: 80 flags: STMT_END_F |
| mysql-bin.000027 | 475 | Xid | 1 | 506 | COMMIT /* xid=199 */ |
| mysql-bin.000027 | 506 | Query | 1 | 574 | BEGIN |
| mysql-bin.000027 | 574 | Table_map | 1 | 622 | table_id: 80 (test.t1) |
| mysql-bin.000027 | 622 | Delete_rows | 1 | 664 | table_id: 80 flags: STMT_END_F |
| mysql-bin.000027 | 664 | Xid | 1 | 695 | COMMIT /* xid=200 */ |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
13 rows in set (0.00 sec)

XID_EVENT

在事务提交时,不管是STATEMENT还是ROW格式的binlog,都会在末尾添加一个XID_EVENT事件代表事务的结束。该事件记录了该事务的ID,在MySQL进行崩溃恢复时,根据事务在binlog中的提交情况来决定是否提交存储引擎中状态为prepared的事务。

ROTATE_EVENT

当binlog文件的大小达到max_binlog_size的值或者执行flush logs命令时,binlog会发生切换,这个时候会在当前的binlog日志添加一个ROTATE_EVENT事件,用于指定下一个日志的名称和位置。

mysql> show binlog events in 'mysql-bin.000028';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000028 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000028 | 120 | Rotate | 1 | 167 | mysql-bin.000029;pos=4 |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)
# at
# :: server id end_log_pos CRC32 0xd965567c Rotate to mysql-bin. pos:

GTID_LOG_EVENT

在启用GTID模式后,MySQL实际上为每个事务都分配了个GTID

譬如:

# at
# :: server id end_log_pos CRC32 0xaeb24aac GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:3'/*!*/;
# at
# :: server id end_log_pos CRC32 0x042ca092 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0xa35beb37 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
insert into test.t1 values(,'b')
/*!*/;
# at
# :: server id end_log_pos CRC32 0x1905d8c6 Xid =
COMMIT/*!*/;
mysql> show binlog events in 'mysql-bin.000033';
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000033 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000033 | 120 | Previous_gtids | 1 | 191 | cad449f2-5d4f-11e6-b353-000c29c64704:1 |
| mysql-bin.000033 | 191 | Gtid | 1 | 239 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:2' |
| mysql-bin.000033 | 239 | Query | 1 | 314 | BEGIN |
| mysql-bin.000033 | 314 | Query | 1 | 417 | insert into test.t1 values(1,'a') |
| mysql-bin.000033 | 417 | Xid | 1 | 448 | COMMIT /* xid=11 */ |
| mysql-bin.000033 | 448 | Gtid | 1 | 496 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:3' |
| mysql-bin.000033 | 496 | Query | 1 | 571 | BEGIN |
| mysql-bin.000033 | 571 | Query | 1 | 674 | insert into test.t1 values(2,'b') |
| mysql-bin.000033 | 674 | Xid | 1 | 705 | COMMIT /* xid=12 */ |
| mysql-bin.000033 | 705 | Rotate | 1 | 752 | mysql-bin.000034;pos=4 |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
11 rows in set (0.00 sec)

PREVIOUS_GTIDS_LOG_EVENT

开启GTID模式后,每个binlog开头都会有一个PREVIOUS_GTIDS_LOG_EVENT事件,它的值是上一个binlog的PREVIOUS_GTIDS_LOG_EVENT+GTID_LOG_EVENT,实际上,在数据库重启的时候,需要重新填充gtid_executed的值,该值即是最新一个binlog的PREVIOUS_GTIDS_LOG_EVENT+GTID_LOG_EVENT。

譬如:

mysql> show binlog events in 'mysql-bin.000033';
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000033 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000033 | 120 | Previous_gtids | 1 | 191 | cad449f2-5d4f-11e6-b353-000c29c64704:1 |
| mysql-bin.000033 | 191 | Gtid | 1 | 239 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:2' |
| mysql-bin.000033 | 239 | Query | 1 | 314 | BEGIN |
| mysql-bin.000033 | 314 | Query | 1 | 417 | insert into test.t1 values(1,'a') |
| mysql-bin.000033 | 417 | Xid | 1 | 448 | COMMIT /* xid=11 */ |
| mysql-bin.000033 | 448 | Gtid | 1 | 496 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:3' |
| mysql-bin.000033 | 496 | Query | 1 | 571 | BEGIN |
| mysql-bin.000033 | 571 | Query | 1 | 674 | insert into test.t1 values(2,'b') |
| mysql-bin.000033 | 674 | Xid | 1 | 705 | COMMIT /* xid=12 */ |
| mysql-bin.000033 | 705 | Rotate | 1 | 752 | mysql-bin.000034;pos=4 |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
11 rows in set (0.00 sec) mysql> show binlog events in 'mysql-bin.000034';
+------------------+-----+----------------+-----------+-------------+------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+------------------------------------------+
| mysql-bin.000034 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000034 | 120 | Previous_gtids | 1 | 191 | cad449f2-5d4f-11e6-b353-000c29c64704:1-3 |
+------------------+-----+----------------+-----------+-------------+------------------------------------------+
2 rows in set (0.00 sec)

mysql-bin.000033日志中的Previous_gtids是cad449f2-5d4f-11e6-b353-000c29c64704:1,GTID是cad449f2-5d4f-11e6-b353-000c29c64704:2和cad449f2-5d4f-11e6-b353-000c29c64704:3,这样,在下一个日志,即mysql-bin.000034中的Previous_gtids是cad449f2-5d4f-11e6-b353-000c29c64704:1-3。

# at
# :: server id end_log_pos CRC32 0x4e84f3b5 Previous-GTIDs
# cad449f2-5d4f-11e6-b353-000c29c64704:-

STOP_EVENT

当MySQL数据库停止时,会在当前的binlog末尾添加一个STOP_EVENT事件表示数据库停止。

譬如:

mysql> show binlog events in 'mysql-bin.000030';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000030 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000030 | 120 | Stop | 1 | 143 | |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
2 rows in set (0.04 sec)
# at
# :: server id end_log_pos CRC32 0xf20ddc85 Stop

参考

1. MariaDB原理与实现

2. MySQL官方文档

MySQL binlog中的事件类型的更多相关文章

  1. mysql语句中把string类型字段转datetime类型

    mysql语句中把string类型字段转datetime类型   在mysql里面利用str_to_date()把字符串转换为日期   此处以表h_hotelcontext的Start_time和En ...

  2. JS中的事件类型和事件属性的基础知识

    周末无聊, 这几天又复习了下JS搞基程序设计3, 想着好记性不如浪笔头哇, 要么把这些东西写下来, 这样基础才能更加扎实么么哒, 知道的同学也可以直接过一下,当做复习,  小姨子再也不用担心我的学习啦 ...

  3. JavaScript 中的事件类型5(读书笔记思维导图)

    Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件. UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...

  4. JavaScript 中的事件类型4(读书笔记思维导图)

    Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件. UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...

  5. JavaScript 中的事件类型3(读书笔记思维导图)

    Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件. UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...

  6. JavaScript 中的事件类型2(读书笔记思维导图)

    Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件: UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...

  7. JavaScript 中的事件类型1(读书笔记思维导图)

    Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件. UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...

  8. MYSQL表中设置字段类型为TIMESTAMP时的注意事项

    在MYSQL中,TIMESTAMP类型是用来表示日期的,但是和DATETIME不同,不同点就不再这里说明了. 当我们在使用TIMESTAMP类型设置表中的字段时,我们应该要注意一点,首先我们在表中新增 ...

  9. 关于java中的事件类型

    java中的Date是为了证明:天才的程序员也会犯错: java中的Calendar是为了证明:普通的程序员也会犯错. ———————————————————— stackoverflow上大部分都推 ...

随机推荐

  1. 【每日一linux命令4】常用参数:

     下面所列的是常见的参数(选项)义: --help,-h                              显示帮助信息 --version,-V                        ...

  2. Asp.Net MVC中使用StreamReader读取“Post body”之应用场景。

    场景:有三个市场(Global.China.USA),对前台传过来的数据有些验证需要细化到每个市场去完成. 所以就出现了基类(Global)和派生类(China.USA) 定义基类(Global)Pe ...

  3. OVS 中的各种网络设备 - 每天5分钟玩转 OpenStack(128)

    上一节我们启用了 Open vSwitch,本节将查看当前的网络状态并介绍 Open vSwitch 涉及的各种网络设备 初始网络状态 查看一下当前的网络状态. 控制节点 ifconfig 显示控制节 ...

  4. Node.js:理解stream

    Stream在node.js中是一个抽象的接口,基于EventEmitter,也是一种Buffer的高级封装,用来处理流数据.流模块便是提供各种API让我们可以很简单的使用Stream. 流分为四种类 ...

  5. 无法访问org.springframework.core.NestedRuntimeException 找不到org.springframework.core.NestedRuntimeException的类文件

    在学习springAOP时,出现如下异常: 无法访问org.springframework.core.NestedRuntimeException 找不到org.springframework.cor ...

  6. nginx服务器安装及配置文件详解

    nginx在工作中已经有好几个环境在使用了,每次都是重新去网上扒博客,各种编译配置,今天自己也整理一份安装文档和nginx.conf配置选项的说明,留作以后参考.像负载均衡配置(包括健康检查).缓存( ...

  7. Flexible 弹性盒子模型之CSS flex-shrink 属性

    实例 让第二个元素收缩到其他元素的三分之一: 效果预览 div:nth-of-type(2){flex-shrink:3;} 浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本号. 紧跟在 - ...

  8. .Net 初步学习笔记之一——.Net 平台与.Net FrameWork框架的关系

    .Net 包含两部分 .Net平台 和.Net FrameWork 框架 1..Net FrameWork框架包含于.Net平台. .Net FrameWork提供环境和支撑保证.Net平台运行. 2 ...

  9. 用 eric6 与 PyQt5 实现python的极速GUI编程(系列04)---- PyQt5自带教程:地址簿(address book)

    [引子] 在PyQt5自带教程中,地址簿(address book)程序没有完全实现界面与业务逻辑分离. 本文我打算用eric6+PyQt5对其进行改写,以实现界面与逻辑完全分离. [概览] 1.界面 ...

  10. JavaScript中undefined与null的区别

    通常情况下, 当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个undefined值.Javascript会自动将声明是没有进行初始化的变量设为undifined. 如果一个变量根本不存在会 ...