前幾天Pacemaker+Corosync的PostgreSQL HA叢集發生了兩次故障,再次提醒了HA的部署要謹慎,維護要細緻。
系統是基于Pacemaker+Corosync的PostgreSQL 1主2從 HA叢集。在資料庫上執行一個delete.從500w的表裡删除13w條記錄,發現Master挂了。 然後自動起來,再執行這個SQL,再次挂。究竟怎麼回事呢?
後來查了Pacemaker的日志,發現是expgsql RA的monitor發生逾時,導緻expgsql RA重新開機PostgreSQL。(遷移門檻值是3,可以重新開機3次,超過3次就會發生主從切換。)
/var/log/messages
corosync.log中發現在發生逾時前,系統負載很高。
/var/log/cluster/corosync.log
系統是4核機,上面的輸出表明系統已經超載,進入限流模式。後面甚至有負載達到49的記錄。
限流模式是Pacemaker的一種保護措施,進入限流模式後Pacemaker會減少自身可以并發執行的job數。 在High CPU load下,限流模式會限制同時隻能有1個job在跑。正常情況下,允許同時運作的最大job數是CPU核數的2倍。
https://github.com/ClusterLabs/pacemaker/blob/master/crmd/throttle.c
擷取CPU LOAD的方式為取/proc/loadavg中第一行的1分鐘負載。
至于負載門檻值,有3個負載級别,不同門檻值有不同的因子(throttle_load_target)
對應的門檻值分别為 load-threshold * throttle_load_target
load-threshold為叢集參數,預設值為80%
判斷是否超過門檻值的方法是用調整後的CPU負載(上面的CPU LOAD除以核心數)和門檻值比較
除了CUP負載,Pacemaker還有IO負載的比較,但是相關函數存在多處錯誤,實際上無效。 無效也好,如果下面這個問題解決了後面會有相反的bug導緻會誤判高IO負載。
不能肯定限流和這次故障是否有必然的聯系。但是在限流下,Pacemaker執行job的能力弱了,系統負載又高,會增大monitor相關job得不到及時的CPU排程進而發生逾時的機率。實際的罪魁禍首還應該是高負載及逾時判斷方法。
搜尋後發現有人遇到過類似問題,處理辦法就是增大monitor的逾時時間。
https://bugs.launchpad.net/fuel/+bug/1464131
https://review.openstack.org/#/c/191715/1/deployment/puppet/pacemaker_wrappers/manifests/rabbitmq.pp
一方面修改增大monitor的逾時時間。線上修改的方法如下:
另一方面,發現系統負載過重,經常跑到100%的CPU,即使沒有HA這檔子事也是個不穩定因素。 通過修改應用,遷移大部分的讀負載到SLave上,有效減輕了Master的壓力。
GitHub遇到過類似的故障,由于遷移到Master負載過高,進而Percona Replication Manager的健康檢查失敗進行了切換,切換後新主的緩存是冷的,負載同樣過高,又切回去。 (幸運的是我們的方案有3次遷移門檻值的保護,不會立刻切。)GitHub權衡後的對策居然是放棄自動切換,隻能由人工發起。
另,Pacemkaer的論壇有幾件高負載導緻corosync token逾時的問題,同樣由于相關job不能及時得到OS排程所緻,該問題虛機上容易發生,特别是有超分的情況下,解決辦法是加大token逾時時間。
系統配置的同步複制,正常情況下2個Slave應該一個是sync,另一個是async。 但是,某個時間發現2個Slave都是async,這對應用系統暫無影響,但是萬一這時Master挂了會影響HA切換。 檢視Master上的rep_mode.conf配置檔案,發現synchronous_standby_names是空。
vi /var/lib/pgsql/tmp/rep_mode.conf
于是,手工修改為node2,再reload一下就OK了。
至于什麼原因導緻的,又仔細檢視了一下RA腳本,未發現疑點,而現場已經不在,無從查起,隻能等下次遇到再說。