binlog中各种event事件介绍

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

 

下面就挑几个重点的说一下:

 

QUERY_EVENT

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

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

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

2. STATEMENT格式中的DML操作

3. ROW格式中的DDL操作

 

 

FORMAT_DESCRIPTION_EVENT

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

 

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

如下:

在binlog文件的头部会有如下信息:

binlog中各种event事件介绍

 

binlog中各种event事件介绍                                                                                  |

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包含了要插入的数据

binlog中各种event事件介绍

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

binlog中各种event事件介绍

binlog中各种event事件介绍

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

binlog中各种event事件介绍

对于QUERY_EVENT事件,是以文本形式记录DML操作的。而对于ROWS_EVENT事件,并不是文本形式,

 

如下,rows 格式的binlog,QUERY_EVENT有grant,create,操作,BEGIN。

binlog中各种event事件介绍

GTID_LOG_EVENT

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

binlog中各种event事件介绍

XID_EVENT

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

每次commit前都会记录xid event;

binlog中各种event事件介绍

 

ROTATE_EVENT

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

binlog中各种event事件介绍

Table_map_log_event

Table_map_log_event是Row Format Binlog中的一种Event。它记录了一个表的元数据信息。例如数据库名,表名和字段的类型等信息。当slave执行row events时,Table_map_log_event的作用有:

  1. - 根据其中的数据库名和表名打开slave上对应的表
  2. - 检测slave上的表的字段类型是否和master上的表的字段类型兼容。如果不兼容,slave会报告错误。
  3. - 将数据转换成slave上表的字段类型。但转换紧限于slave和master的字段类型是兼容的情况。

binlog中各种event事件介绍

STOP_EVENT

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

binlog中各种event事件介绍

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。

binlog中各种event事件介绍


 

事物中的事件顺序

在一个事务中,会有事务开始的事件,事务提交的事件,也会有真正做事的事件,比如write_rows等,它们之间的顺序,会与时间戳有一点关系,如下不同的颜色表示不同的event::

GTID在最前面,它的时间是6:40:12,writes_rows在最中间,它的时间是6:40:14,这之间有什么关系呢?

# at 1081
#171109  6:40:12 server id 138  end_log_pos 1146 CRC32 0xf9d62761       GTID    last_committed=4        sequence_number=5       rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= '807de6b3-c4d3-11e7-954f-000c29b46750:5'/*!*/;

# at 1146
#171109  6:40:12 server id 138  end_log_pos 1218 CRC32 0x0c4ebfd3       Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1510180812/*!*/;
BEGIN

/*!*/;
# at 1218
#171109  6:40:12 server id 138  end_log_pos 1266 CRC32 0x6aec281d       Table_map: `test`.`t1` mapped to number 108
# at 1266

#171109  6:40:14 server id 138  end_log_pos 1312 CRC32 0x2c0cfa4e       Write_rows: table id 108 flags: STMT_END_F
### INSERT INTO `test`.`t1`
### SET
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Japan' /* VARSTRING(120) meta=120 nullable=1 is_null=0 */

# at 1312
#171109  6:40:12 server id 138  end_log_pos 1343 CRC32 0xfe8292de       Xid = 35
COMMIT/*!*/;

 

mysql事务提交时做的操作有三部分,

  • 根据执行后的上下文环境,生成一个GTID事件。
  • 组装事务产生的GTID。
  • 提交到各种存储引擎。