0%

MySQL事务边界判断

前言

在MySQL的binlog中,一个事务一般由多个binlog events组成。在复制(或者崩溃恢复)等场景中,为了保证数据的一致性,需要根据当前已经存在binlog中的event来判断事务的完整性,以决定复制的位置(或者是否需要truncate不完整的事务)。MySQL 5.7开始,引入了类Transaction_boundary_parser来对一个完整事务做边界的判断。事务边界判断的源代码包含在sql/rpl_trx_boundary_parser.h(cc)两个文件中,以下内容是相关源码的分析。

事件的边界类型

在rpl_trx_boundary_parser.h中,MySQL的binlog event被划分为以下几类:

  • EVENT_BOUNDARY_TYPE_GTID,主要是Gtid_log_event;
  • EVENT_BOUNDARY_TYPE_BEGIN_TRX, 包括Query_log_event(BEGIN)和Query_log_event(XA START);
  • EVENT_BOUNDARY_TYPE_END_TRX,包括Xid, Query_log_event(COMMIT), Query_log_event(ROLLBACK), XA_Prepare_log_event等事件;
  • EVENT_BOUNDARY_TYPE_END_XA_TRX,主要是Query_log_event(XA ROLLBACK);
  • EVENT_BOUNDARY_TYPE_PRE_STATEMENT,包括User_var, Intvar, Rand上下文相关的event;
  • EVENT_BOUNDARY_TYPE_STATEMENT, 包括其他所有的Query_log_events和DML事件(Rows, Load_data等);
  • EVENT_BOUNDARY_TYPE_IGNORE, 包括所有非DDL/DML事件,例如:Format_desc, Rotate, Incident, Previous_gtids, Stop等;
  • EVENT_BOUNDARY_TYPE_ERROR, 非以上类型的event归结为此类;

事务序列的定义

DDL事务序列

1
2
3
DDL-1: [GTID]
DDL-2: [User] [Intvar] [Rand]
DDL-3: Query

DML事务序列

1
2
3
4
DML-1: [GTID]
DML-2: Query(BEGIN)
DML-3: Statements
DML-4: (Query(COMMIT) | Query([XA] ROLLBACK) | Xid | Xa_prepare)

说明

  • DDL和DML事务由不同的binlog事件序列组成,在开启GTID的时候,都是以GTID事件开始;
  • DML事务的开始和结束有相对明显的事件标识,通常以BEGIN或者XA START事件作为事务的开始,以COMMIT/ROLLBACK等事务的提交作为结束;
  • DDL事务的结束相对难以确定,其中DDL-2中的三种binlog事件是一种预处理事件,User代表语句中使用了用户变量,Intvar代表语句中使用了INSERT_ID或LAST_INSERT_ID,Rand代表语句中使用了Rand()函数, 在ROW格式的binlog中,不存在预处理事件;

事务边界判断的状态机

根据以上事务序列的定义,可以将事务边界的判断抽象为一个状态机,该状态机包含一下几种状态:

  • EVENT_PARSER_NONE,开始状态,在遇到DDL-3或者DML-4类型的event后,跳转到该状态,表示上一个事务的结束,一个新事物的开始;
  • EVENT_PARSER_GTID, GTID状态,在遇到DDL-1或者DML-1类型的event(其实就是Gtid_log_event)后,跳转到该状态,不开启GTID时,不存在该状态;
  • EVENT_PARSER_DDL, DDL状态,在遇到DDL-2类型的event后,跳转到该状态,表示当前在一个DDL事务中;
  • EVENT_PARSER_DML, DML状态,在遇到DML-2类型的event(BEGIN)后,跳转到该状态,表示当前在一个DML事务中;
  • EVENT_PARSER_ERROR, 错误状态,遇到非正常事件序列后,跳转到该状态;

状态机的跳转逻辑图如下:

注意:

不管前驱状态如何,只要遇到错误的边界类型,状态机都会转移成ERROR,为了使逻辑图清晰,这部分没有画!

参考

  • 本文内容来自Mysql 5.7源代码sql/rpl_trx_boundary_parser.h(cc)两个文件,感兴趣可研究一下。
如果对您有帮助