MySQL:MGR(单主)备节点MTS并发原则

最近遇到一个案例MGR备节点出现了hang死的问题,考虑到和备节点的并发有关,则学习了一下这部分。现记录如下。这里约定,

  • last commit:代表gtid event中的last commit
  • seq number:代表gtid event中的seq number
  • gno:代表gtid uuid:1 中1,就是gno

一、SQL线程的并发原则

这部分实际上不管是在MGR还是在主从中都是基于last commit进行并发的,在主从中我们可以通过设置参数,

  • transaction_write_set_extraction=XXHASH64 :设置writeset算法,一旦设置了这个参数则主库会计算事务中每行数据关于主键和唯一键的writeset(add_pke函数)。
  • binlog_transaction_dependency_tracking=WRITESET:主库根据Writeset_history在哦commit_order算法的基础上继续下降last commit。

然后从库接收到这些基于WRITESET生成的event后,SQL线程会判断last commit来判断并发度。但是在MGR中确要复杂一些了,因为MGR中在传输event的时候主库的gtid event根本就没有生成,更别说生成last commit了,它传输的event也不是简单的读取binlog文件,下面我们来看看MGR中的备节点节点如何生成last commit的。

二、MGR中last commit/seq number和GTID序号(gno)的生成方式

这里直接跳过了各种gcs和xcom处理,当做了一个黑盒。

  • 主库在group_replication_trans_before_commit 处建立一个gtid event,这个gtid event并没有包含任何有用的gtid信息。
  • 主库在group_replication_trans_before_commit 将writeset封装到Transaction_context_log_event中。
  • 连同事务产生的event一起交给gcs和xcom进行传输和协商
  • 备库xcom收到协商好的事务信息后进行解析后通过进行pipeline处理
  • applier 通道中,pipeline中的Certification_handler::handle_event进行处理填充认证数据库/进行验证/生成gtid event中的信息
  • applier 通道中,pipeline中的Applier_handler::handle_event将事务的信息写入到relay log。
  • applier 通道中,SQL线程进行分发和worker线程进行应用

那么这里我们需要重点关注的就是Certification_handler::handle_event中如何生成last commit和gno的。

  1. 首先Certification_handler::handle_event如果发现是Transaction_context_log_event,则进行缓存
  2. 如果Certification_handler::handle_event如果发现是Gtid_log_event,则调用Certification_handler::handle_transaction_id进行处理。

这个步骤首先调用Certifier::certify,其主要功能完成认证并且完成Gtid last commit和gno的生成,其中认证步骤为多主需要的这里不考虑。首先处理last commit,将其设置为冲突认证数据库中维护的最低值如下,

int64 transaction_last_committed = parallel_applier_last_committed_global<br>