多从库时半同步复制不工做的BUG分析

**做者:胡呈清、黄炎**
问题描述

MySQL版本:5.7.16,5.7.17,5.7.21php

存在多个半同步从库时,若是参数 rpl_semi_sync_master_wait_for_slave_count=1,启动第1个半同步从库时能够正常启动,启动第2个半同步从库后有很大几率 slave_io_thread 停滞(复制状态正常,Slave_IO_Running: Yes,Slave_SQL_Running: Yes,可是彻底不一样步主库 binlog )mysql

复现步骤

1.主库配置参数以下:
rpl_semi_sync_master_wait_for_slave_count = 1
rpl_semi_sync_master_wait_no_slave = OFF
rpl_semi_sync_master_enabled = ON
rpl_semi_sync_master_wait_point = AFTER_SYNC
2.启动从库A的半同步复制 start slave,查看从库A复制正常
3.启动从库B的半同步复制 start slave,查看从库B,复制线程正常,可是不一样步主库 binlogsql

分析过程

首先弄清楚这个问题 ,须要先结合MySQL其余的一些状态信息,尤为是主库的 dump 线程状态来进行分析:源码分析

  1. 从库A启动复制后,主库的半同步状态已启动:

图片描述

再看主库的 dump 线程,也已经启动:
图片描述spa

再看主库的 error log,也显示 dump 线程(21824)启动成功,其启动的半同步复制:
图片描述线程

2.从库B启动复制后,主库的半同步状态,仍是只有1个半同步从库 Rpl_semi_sync_master_clients=1:
图片描述code

再看主库的 dump 线程,这时有3个 dump 线程,可是新起的那两个一直为 starting 状态:
图片描述
图片描述图片

再看主库的 error log,21847 这个新的 dump 线程一直没起来,直到1分钟以后从库 retry ( Connect_Retry 和 Master_Retry_Count 相关),主库上又启动了1个 dump 线程 21850,仍是起不来,而且 21847 这个僵尸线程还停不掉:get

图片描述

3.到这里咱们能够知道,从库B slave_io_thread 停滞的根本缘由是由于主库上对应的 dump 线程启动不了。如何进一步分析线程调用状况?推荐使用 gstack 或者 pstack(实为gstack软链)来查看线程调用栈,其用法很简单:gstack <process-id>同步

4.看主库的 gstack,能够看到 24102 线程(旧的复制 dump 线程)堆栈:
图片描述

能够看到 24966 线程(新的复制 dump 线程)堆栈:
图片描述

两线程都在等待 Ack_Receiver 的锁,而线程 21875 在持有锁,等待select:

图片描述

理论上 select 不该hang, Ack_receiver 中的逻辑也不会死循环,请教公司大神黄炎进行一波源码分析。

5.semisync_master_ack_receiver.cc 的如下代码造成了对互斥锁的抢占, 饿死了其余竞争者:
图片描述

在 mysql_mutex_unlock 调用后,应适当增长其余线程的调度机会。
试验: 在 mysql_mutex_unlock 调用后增长 sched_yield();,可验证问题现象消失。

结论

1.从库 slave_io_thread 停滞的根本缘由是主库对应的 dump thread 启动不了;
2.rpl_semi_sync_master_wait_for_slave_count=1 时,启动第一个半同步后,主库 ack_receiver 线程会不断的循环判断收到的 ack 数量是否 >= rpl_semi_sync_master_wait_for_slave_count,此时判断为 true,ack_receiver基本不会空闲一直持有锁。此时启动第2个半同步,对应主库要启动第2个 dump thread,启动 dump thread 要等待 ack_receiver 锁释放,一直等不到,因此第2个 dump thread 启动不了。

相信各位DBA同窗看了后会很震惊,“什么?竟然还有这样的bug...”,这里要说明一点,这个bug 触发是有概率的,可是概率又很大。这个问题已经由我司大神在1月份提交了 bug 和 patch:https://bugs.mysql.com/bug.ph...,加上本人提交SR后时不时的催一催,昨天官方终于确认将修复在 5.7.23(官方最终另有修复方法,没采纳这个 patch,期待我司大神下期分析官方的修复代码)。

相关文章
相关标签/搜索