mysql主从复制出现Waiting for Slave Worker to release partition

实为吾之愚见,望诸君酌之!闻过则喜,与君共勉 

第一节   并行复制

Mysql5.6的mts(并行复制)是基于database来分发事务的,coordinator(原来的sql thread)按照slave worker与db的对应关系进行处理来分发事务给相应的slave worker,slave worker代替了sql thread来执行事务中的event。并且mysql默认认为数据是以database来分布的,跨库的事务在slave应用的时候可能就需要等待了。

Waiting for Slave Worker to release partition第一次看到是在开启MTS的mysql5.6主从复制的时候,在Slave_SQL_Running_State:出现Waiting for Slave Worker to release partition,Slave_SQL_Running_State的状态比较多,但是这个状态翻译过来是指“等待slave worker 释放 分区(partitions)”,其中的partitions解释成中文不是很正确,partitions可以理解成”按照slave worker与db的对应关系进行分发事务后的对象”(有更好的解释请留言),它既不是事务也不是event,也不是单纯的对应关系,起码可以确定这种情况并不是异常的情况(大部分时候),slave worker正在应用coordinator分配的内容但是还没结束,coordinator需要等待之前分配的内容应用完成才可以继续分配(coordinator还没有将其放入slave worker的queue),下面尝试测试和复现Waiting for Slave Worker to release partition。

当不开启并行复制时(slave_parallel_workers 0),show processlist是这样的:

mysql主从复制出现Waiting for Slave Worker to release partition

当开启并行复制时(slave_parallel_workers为2),show processlist是这样的:

mysql主从复制出现Waiting for Slave Worker to release partition

区别是增加了两个slave worker进程,原来的sql thread变成了 coordinator。

 

第二节   测试和复现

2.1 创建测试数据

1,创建两个测试的database:slavetest,slavetest1

2,在这两个db中分布创建一张表test,向里面写入200w左右的测试数据

通过测试一些场景,通过其结果来反应一些问题,以下测试多是基于自建mysql进行

2.2 测试1

确认slave worker与db的在串行执行时对应关系,先打开一个session,分别执行

update slavetest.test set trade='slavetest';

update slavetest1.test set trade='slavetest1';

查看slave的slave worker状态,找到slavetest对应的slave worker

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

通过上面测试slavetest对应的slave worker的进程id为5812476

使用同样的方法,得出如下对应:

slavetest     5812476

slavetest1        5812475

这样单线程执行的时候,两个db在执行update更新时,coordinator都分配给了5812476的slave worker

2.3 测试2

确认slave worker与db的在并行执行时对应关系,同事打开2个session,每个session分别执行更新,中间间隔10s
update slavetest.test set trade='slavetest11';

update slavetest1.test set trade='slavetest22';

查看slave的slave worker状态,找到slavetest对应的slave worker(可以写一个脚本来循环执行show processlist监控)

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

通过执行信息看,slavetest1的事务先完成,slavetest2的事务后完成,看下slave的进程信息:

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

过滤后如下:

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition

通过上面测试并不能在slave上执行完这两个事务的时候,保证一个slave worker完全对应其中的一个dbname(个人以为上一个事务里面,slave worker与db的对应是不会变的),暂且得出的结论是当并行执行两个db的事务的时候,其中的两个slave worker都产生了影响。

这样多线程执行的时候,两个db在执行update更新时,coordinator会把事务分配给两个slave worker同时并行执行,并且也出现了Waiting for Slave Worker to release partition,并且还出现了Waiting for Slave Worker queue,按照之前的描述,mysql假设数据是按照database来分布的,所以不会存在跨库的情况,下面进行事务跨库的测试

2.4 测试3

确认slave worker与db的在一个事务里跨库执行时对应关系,只打开1个session,执行:
begin;

update slavetest.test set trade='slavetest1';

update slavetest1.test set trade='slavetest2';

commit;

查看slave的slave worker状态,找到slavetest对应的slave worker(可以写一个脚本来循环执行show processlist监控)

mysql主从复制出现Waiting for Slave Worker to release partition

模拟一个事务内跨库执行更新,查看slave的进程信息:

mysql主从复制出现Waiting for Slave Worker to release partition

mysql主从复制出现Waiting for Slave Worker to release partition


通过过滤的结果看,执行event的进程只有一个5812476,coordinator并没有分配给5812475的slave worker来执行,且也出现了Waiting for Slave Worker to release partition

 

通过测试和复现问题,Waiting for Slave Worker to release partition一般来说是一个正常的中间状态,但是也有可能出现问题,有一些特殊情况可以参考:

https://bugs.mysql.com/bug.php?id=73066

https://bugs.mysql.com/bug.php?id=72794

另外包括Waiting for Slave Worker queue,System lock等状态大部分也是正常的中间状态

上一篇:利用Serverless Kubernetes和Kaniko快速自动化构建容器镜像


下一篇:JAVA常见算法题(十九)