一、故障時間:
發生時間:2015.11.17 凌晨2:10點左右
解決時間:2015.11.17 早上8:40分左右
二、故障解決人員:
XXX
三、故障現象:
XXX WEB、系統無法登陸,通過堡壘機連接系統完全無響應,數據庫主庫大量的查詢被阻塞,插入更新語句無法執行
四、故障排查:
首先通過堡壘機登陸XXX系統,查看狀態,但是因系統無響應,只有聯繫idc機房人員進行手動重啓系統。同時登陸平臺數據庫主庫系統查看MySQL進程狀態,顯示出大量的表需要等待XXX_order表的tableflush狀態完成(P-2所示)。大約10分鐘後XXX系統啓動完成,登陸後查看系統狀態,各個服務都運行良好。只是一直收到監控系統的報警:系統進程在不斷增加。應該可以很清楚的知道是因爲數據庫的XXX_order和XXX_task_queue表需要完成flushtable,而長時間沒有完成導致的。
五、故障解決:
目前的主要問題就在如何解決阻塞的問題,當時通過查看系統進程大概有3000多個Waitingfor table flush的SQL,全部是XXX庫(XXX_order)相關的表(P-2所示)。手工kill掉一些select類型的SQL並不能起作用,這時候應該找到產生阻塞的具體SQL纔對。之前對數據庫系統做了一個監控系統進程狀態的腳本,打開日誌文件,查看裏面具體的SQL(P-3所示)找到執行時間最長的那個,kill掉對應的SQL ID應該就釋放了阻塞。大量的Waiting for table flush 狀態消失,系統恢復正常。
P-1
P-2
P-3
六、故障原因:
因一個性能較差通過手工執行的SQL在通過堡壘機進行查詢時手工終止(ctrl+c)但是在MySQL實例已經開始了Copying數據到tmp表中,並沒有結束掉,還是一直在數據庫中執行。查詢執行時間長達10多個個小時。同時備份的腳本啓動,開始出現阻塞的時間在凌晨2點鐘左右,那個時間正好是數據庫備份開始執行的時間,mysqldump會發出flushtables的動作,因爲SQL執行的慢,導致無法完成mysqldump需要對XXX_order和XXX_task_queue表的tableflush動作導致阻塞了其他查詢,插入更新等對XXX_order和XXX_task_queue表的請求的堆積,同時XXX系統相關的計劃任務很多是每一分鐘執行一次,造成XXX的計劃任務不能及時執行完成,系統進程數量陡增(P-4所示),造成XXX系統崩潰。
P-4
七、問題解決方案
1. 監控MySQL Processlist 的xxx_select賬號執行的時間,如果超過1800秒就將其線程進行kill掉終止執行。
2. 通過Nagios監控MySQL Processlist中出現Waitingfor table flush、Waitingfor table metadata lock和flushtable with read lock的數量,如果超過5個就要發出報警,運維人員介入處理,根據日誌來查找具體原因
3. 搭建一個新的專門處理查詢任務的從庫,此從庫不影響業務
八、故障後的反思:
通過這次故障應該吸取教訓:
1. 對數據庫的任何操作都要謹慎、敬畏,因爲數據是企業的生命。當進行增刪改查的時候就要知道造成的後果是什麼?操作前做好充分的測試,再去線上進行執行,比如看SQL的執行計劃是否是最優化的性能、是否會造成數據的不一致問題,主從是否會出現中斷等。不會對現有的業務造成影響,否則就不應該進行線上操作,切記!
2. 運維在系統監控這邊執行的不是很到位,需要自我反省。通常在手機接收到報警的時候第一時間進行處理(凌晨兩點左右),當時在看到手機報警的時候沒有看清是系統沒有響應了(熟睡中醒來看什麼都迷糊)手機登錄管理系統能ping的通XXX系統的網絡,結合報警類型來看只是暫時的無響應,但當收到大量報警時候,發現是比較嚴重的問題了,着手處理問題的時間在早上7點半左右,這期間有充足的時間去處理。並且監控系統在問題發生之前就已經預警了,並沒有引起重視!才造成後續更嚴重的問題!對於以後產生環境的報警應該加以重視,不能掉以輕心,將問題在萌芽狀態就要及時發現並處理!
3. 對系統運行時狀態的即時轉存儲對於解決問題有很大的幫助,所以應該考慮對系統狀態做快照處理保存,以便查找問題出現的根本原因。