多從庫時半同步複製不工做的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,期待我司大神下期分析官方的修復代碼)。

相關文章
相關標籤/搜索