参数设置:

slave_parallel_type=logical

slave_parallel_workers=4(工作的线程数,不包含协调线程)

MTS持久化信息场景(master_info_repository和relay_log_info_repository为table的前提)

slave_master_info表:由于IO线程进行更新,超过sync_master_info设置更新,单位event个数

relay_log_info_repository表:由sql 协调线程进行执行检查点的更新时候进行更新

slave_worker_info表 由工作线程每次提交事物的时候更新

 

 

协调线程的分发机制:

协调线程在event的发布中主要完成下面两个工作:

1.判断事物是否可以并行回放

2.判断事物由哪个工作线程进行回放

重要:和单SQL线程执行流程不同的是,主要体现在函数APPLY_EVENT_AND_UPDATE_POS下面,对于单线程而言会完成event的应用,而对于MTS而言就是只会完成event的发布,具体的应用将会由工作线程完成。

 

步骤解析:

1.如果gtid_log_event代表事物开始,将本事物加入到GAQ队列中

2.将GTID_LOG_EVENT加入到curr_group_da队列中暂存

3.获取GTID_LOG_EVENT中的last commit 和seq number值

4.获取current_lwm值,这个值代表的是所有GAQ队列上还没有提交完成事物中最早的哪个事物的前一个已提交事物的seq number,可能后面的事物已经提交完成了,如果都已经提交完成就是取最新的提交的事物的seq number

mysql mts mysql MTS并行回放_工作线程

 

 seq number从左向右递增,在GAQ中由三种值:

X:已经做了检查点,在GAQ中出队的事物

x:已经提交完成的事物

o:没有提交完成的事物

 

5.将GTID_LOG_EVENT中的last commit 和当前current_lwm进行比较:

1.如果last commit小于等于current_lwm表示可以进行并行回放

2.如果last commit 大于current_lwm则表示不能进行并行回放,这个时候协调线程就需要等待了,直到小于等于的条件成立。成立之后协调线程会被工作线程唤醒,等待期间状态被置为“ waiting for dependent transaction to commit"

 

6.如果是query_event则加入到curr_group_da队列暂存

7.如果是MAP_event进行工作线程的分配

1.如果有空闲的线程则分配完成,继续

2.如果没有空闲的工作线程则等待空闲的工作线程。这种情况下状态会置为”waiting for slave workers to process their queues“。

8.将GTID_LOG_EVENT和QUERY_EVENT分配给工作线程。任务队列的大小为16384

9.MAP_EVENT分配给工作线程,同上

10.delete_event 分配给工作线程,同上

11.xid_event 分配给工作线程,但是这里还需要额外的处理,主要处理一些和检查点相关的信息,如果检查点处于这个事务上,那么这些信息会出现在表slave_worker_info中,并且会出现在show slave status。也就是说show slave status 中很多信息来自MTS的检查点

12.如果上面的EVENT分配过程大于2分钟,可能会出现一个日志如下:

mysql mts mysql MTS并行回放_并行执行_02

 

 

mysql mts mysql MTS并行回放_检查点_03

 

 

mysql mts mysql MTS并行回放_mysql mts_04

 

 

并行回放判断的列子:

mysql mts mysql MTS并行回放_并行执行_05

 

 解析:

1.last commit 22,seq number 23)这个事物会在(last commit 21,seq number 22)事物执行之后完成,因为last commit<= seq number,后面的事物直到last commit 22,seq number 30),都是可以并行执行,

如下三个事物:

last commit 29,seq number 31

last commit 30,seq number 32

last commit 27,seq number 33

基于writeset的复制的并行明显特征就是last commit可能比上一个事物更小。这就是根据writeset的历史MAP信息计算出来的。因此还是根据上面的规则他们三个是可以并行执行的,原因:

last commit 29<= current_lwm 30

last commit 30<= current_lwm 30

last commit 27<= current_lwm 30

但是如果last commit 22,seq number 30,这个事物之前有一个大事物没有执行完成的话,那么current_lwm的取值将不会是30.比如last commit 22,seq number  27)这个事物是大事物那么current_lwm会标记为26,上面的三个事物将会被堵塞,并且分配last commit 29 seq number 31)的时候就已经被堵塞了,原因如下:

last commit 29> current_lwm 26

last commit 30> current_lwm 26

last commit 27> current_lwm 26

 

因此在我们并行规则下,last commit越小获得并发的可能性越高。

 

许多文章都是从书本获取,并非自己原创,为了自己更好的记忆和学习,如果涉及版权,请说明,我会删除。