閱讀689 返回首頁    go 技術社區[雲棲]


MySQL集群節點宕機,數據庫腦裂!如何排障?

作者介紹

王晶中國移動DBA,負責“移動雲”業務係統的數據庫集成架構設計、運維、優化等工作;擅長技術領域MySQL,獲Oracle頒發的“MySQL DBA”官方認證,熟悉MySQL複製結構、MHA、cluster等多種架構及運維優化。

 

發現故障的時間正值大年初二,在各種鋪天蓋地的拜年信息和微信紅包之中,我發現了手機上的這條告警通知:

 

PROBLEM:Disaster: Galera cluster has node down。我生產環境的Galera集群有一個節點宕機了。

 

可能有的人不太熟悉MySQL Galera集群,下麵先介紹一下出故障的集群信息。

 

PXC:  

 

我們生產上用的是Percona的一個MySQL分支版本,PerconaXtradb Cluster,簡稱PXC,這是一個可以實時同步的MySQL集群,基於廣播write set和事務驗證來實現多節點同時commit,衝突事務回滾的功能。強數據一致性保證。

 

Galera Replication原理總結:  

 

1. 事務在本地節點執行時采取樂觀策略,成功廣播到所有節點後再做衝突檢測;

2. 檢測出衝突時,本地事務優先被回滾;

3. 每個節點獨立、異步執行隊列中的WS;

4. 事務T在A節點執行成功返回客戶端後,其他節點保證T一定會被執行,因此有可能存在延遲,即虛擬同步。

 

Galera複製的架構圖:  

 

20170216101658836.jpg

 

Galera flow control:  

 

Galera是同步複製(虛擬同步)方案,事務在本地節點(客戶端提交事務的節點)上提交成功時,其它節點保證執行該事務。在提交事務時,本地節點把事務複製到所有節點,之後各個節點獨立異步地進行certification test、事務插入待執行隊列、執行事務。然而,由於不同節點之間執行事務的速度不一樣,長時間運行後,慢節點的待執行隊列可能會越積越長,最終可能導致事務丟失。

 

Galera內部實現了flow control,作用就是協調各個節點,保證所有節點執行事務的速度大於隊列增長速度,從而避免丟失事務。

 

實現原理很簡單。整個Galera Cluster中,同時隻有一個節點可以廣播消息(數據),每個節點都會獲得廣播消息的機會(獲得機會後也可以不廣播),當慢節點的待執行隊列超過一定長度後,它會廣播一個FC_PAUSE消息,所以節點收到消息後都會暫緩廣播消息,直到該慢節點的待執行隊列長度減小到一定長度後,Galera Cluster數據同步又開始恢複。

 

搞清楚上麵的背景原理之後,繼續說明我的排障過程。

 

問題描述  

 

1月29日早10點08分接收到Zabbix告警信息,生產環境某子係統數據庫集群節點1、2分別報活躍線程數超閥值,而且不斷升高。

 

從業務側嚐試訪問了一下該子係統,發現係統頁麵一直無法正常查詢數據及修改數據。登陸服務器查看CPU、IO、內存情況均空閑。說明累計的活躍線程過高,已經影響到業務的正常訪問了。

 

問題分析  

 

1、登陸Zabbix告警節點1、2查看數據庫show global status like ‘Threads_running’情況發現Threads_running線程不斷增高。

 

節點1:

| Threads_running|  100     |

 

節點2:

| Threads_running|  110     |

 

2、繼續查看節點1、2數據庫的show processlist的情況,發現存在很多線程停在wsrep in pre-commit stage狀態(這意味著很多線程已經在節點發出commit,但將該SQL發送到其他節點是處於獨立異步地進行certification test、事務插入待執行隊列的狀態)。這裏就明了為什麼會有活躍線程不斷增加了,原來是線程都停留在wsrep in pre-commit stage狀態。

 

3、進一步查找為什麼會有線程一直停留在wsrep in pre-commit stage狀態,show global status like ‘%wsrep%’,發現1、2節點接受隊列並無阻塞,也沒有發出流控。

 

但wsrep_evs_delayed報節點3的4567端口連接延遲。查看節點1、2錯誤日誌發現報“WSREP: (40a252ac, 'tcp://節點2:4567') reconnecting to 67f667d2 (tcp://節點3:4567), attempt 0”。查看節點3的錯誤日誌與wsrep_evs_delayed運行參數則報相反信息,連接節點1和節點2的4567端口延遲。

 

這裏需要解釋一下4567端口的作用(wsrep_provider_options中的gmcast.listen_addr項:主要作用是集群內監聽組員狀態,組員之間的通信(握手,鑒權,廣播,寫入集的複製)。

 

此時,問題原因已經明朗了,因為節點3與節點1、2的4567端口一直連接有延遲,所以在節點1、2執行的請求無法及時的複製給節點3執行,導致節點1、2的活躍線程一直執行不完。

 

節點1:

+------------------------------+-------------+

| Variable_name                | Value       |

+------------------------------+-------------+

| wsrep_local_recv_queue       | 0          |

| wsrep_local_recv_queue_avg   | 0.008711    |

| wsrep_flow_control_paused    | 0.000000    |

| wsrep_flow_control_sent      | 0          |

| wsrep_flow_control_recv      | 0          |

| wsrep_evs_delayed             | 節點3:4567 |

+------------------------------+-------------+

 

節點2:

+------------------------------+-------------+

| Variable_name                | Value       |

+------------------------------+-------------+

| wsrep_local_recv_queue       | 0           |

| wsrep_local_recv_queue_avg   | 0.006193    |

| wsrep_flow_control_paused    | 0.000000    |

| wsrep_flow_control_sent      | 0           |

| wsrep_flow_control_recv      | 0          |

| wsrep_evs_delayed             |節點3:4567 |

+------------------------------+-------------+

 

4、因查詢數據庫狀態除wsrep_evs_delayed報連接延遲,其他並無異常現象,初步懷疑是網絡原因造成,排查網絡後,發現是因核心交換機與接入交換機之間的光模塊損壞導致丟包,所以影響部分數據庫集群之間的通信,才會出現以上問題。

 

在網絡修複期間,因數據庫集群節點3延遲丟包嚴重,被數據庫集群仲裁後踢出了集群,剩餘的節點1和節點2在運行了大約半小時後也因延遲丟包嚴重,出現了腦裂現象。

 

這時緊急將數據庫集群3個節點關閉,然後在每個節點執行mysqld_safe --wsrep-recover命令找出最新事務號節點作為主節點啟動,並在故障期間保持單節點運行。待網絡故障消除後,逐一啟動節點2、3,係統數據庫集群恢複正常。

 

問題回顧  

 

1、 在PXC環境中,如果集群各個節點的通信端口(4567)因為網絡的原因出現異常(因為集群節點間通信采用的是同一網段,因此是共性的原因),應及時采取相應措施防止腦裂情況出現。例如上麵故障中,因網絡原因導致集群節點數從3個變為2個,這時就應該及時地關閉剩餘2個節點中的一個節點,讓業務隻跑在單節點上,還能避免出現腦裂的情況。至少業務不會因此終斷。

 

否則剩餘的兩個節點很快也會被網絡丟包拖垮,會導致整個集群都停止服務,影響業務。當然在非多主的集群中也可以通過設置“SET GLOBAL wsrep_provider_options=’pc.ignore_sb=true’;”來取消集群判斷腦裂的情況(多主環境中不建議使用)。

 

2、可以將wsrep_evs_delayed作為一個監控項進行監控,並結合網絡監控進行適當的告警。

原文發布時間為:2017-02-16

本文來自雲棲社區合作夥伴DBAplus

最後更新:2017-05-15 19:25:01

  上一篇:go  從0開始搭建堅不可摧的Web係統主流架構
  下一篇:go  五步七招,開啟最強DDoS攻防戰!