節假日處理資料庫集群異常小記

楊建榮的學習筆記 發佈 2022-02-07T12:29:35+00:00

今天還在假期狀態中,大概在10:30左右的時候,收到一條簡訊報警,提示一個資料庫集群的中間件內存報警了,但是不到1分鐘的時間,就提示報警恢復了,但是在11:00左右的時候,接到了研發同學的反饋,說這個資料庫集群的只讀服務貌似有些問題,想讓我幫忙看一下到底有什麼問題,整個集群的架構

今天還在假期狀態中,大概在10:30左右的時候,收到一條簡訊報警,提示一個資料庫集群的中間件內存報警了,但是不到1分鐘的時間,就提示報警恢復了,但是在11:00左右的時候,接到了研發同學的反饋,說這個資料庫集群的只讀服務貌似有些問題,想讓我幫忙看一下到底有什麼問題,整個集群的架構模式類似下面的形式,現在提示是黃色部分的只讀資料庫中間件有問題。

因為節前也做了巡檢,而且這個只讀服務已經運行了很長時間了,差不多有3年以上,所以我對於這個問題的初步印象是資料庫中間件異常,通常是一些大查詢導致的內存異常,應該重啟一下就可以了,本來打算是讓同事去處理一下的,過節了還是自己上吧。

因為涉及的是只讀節點,對於線上業務是沒有直接影響的,所以處理問題的方式會和讀寫節點的方式有一些差別。

登錄到了伺服器端之後,發現問題現象比較蹊蹺,首先是我通過本地登錄的方式嘗試連接到資料庫中間件,但是出現了卡頓,遲遲沒有進入命令行,我想這個可能是內存的問題,因為之前在其他環境出現過類似的中間件假死的狀態,需要重啟一下中間件,所以重啟後繼續驗證,發現問題沒有改善,查看中間件日誌,提示客戶端的一些連接是異常的,而且從之前的日誌中發現在今天是觸發了一次OOM導致內存異常。

於是開始分析是不是系統層出現了問題,比如內存使用率等等,但是查看系統負載和磁碟,CPU等使用情況沒有發現明顯的異常,所以關注點還是在中間重啟,比如kill掉多餘的進程進行重啟,但是重啟無果後,準備進行終極大殺器-重啟伺服器。

在重啟伺服器之前和系統的同事也打了招呼,避免出現伺服器無法啟動的尷尬場景,重啟的過程很順利,但是中間件的服務狀態還是依舊,依舊是卡,情況在一些停頓之後有一些改善,沒有那麼卡了,但是實際測試的時候,連接到中間件使用show processlist等命令均產生了卡頓無響應。

所以這個時候的關注點開始下移,我開始關注中間件的配置文件是否有變化,或者是自動化運維任務做了調整等,這個時候我從歷史的備份中開始比對配置文件的變化情況,在做了多重備份之後,使用昨天的配置文件覆蓋了今天的,但是重啟之後依舊無果。

在多次查看日誌無果的情況下,我在懷疑是不是防火牆產生了異常,比如有的服務以前是長連接,如果中間件異常後嘗試重連,理由感覺很牽強而且不夠嚴謹,但是還是試著做了這樣的嘗試,顯然沒有效果。

所以到了這個時候,已經做了很多嘗試,但是效果都不明顯,於是開始認真查看日誌的異常情況,是否是數據節點出現了問題,逐一檢查了配置和負載都沒有發現異常,這個時候我開始從一些不明顯的異常日誌入手,比如提示中間件連接數據節點的時候連接被拒絕和關閉,於是我開始仔細的通過mysql命令測試真實的連接情況。

配置文件中的信息如下:

<dataHost name="localhost4" maxCon="1000" minCon="10" balance="0"                writeType="0" dbType="mysql" dbDriver="native" >                <heartbeat>select user()</heartbeat>                <writeHost host="hostM4" url="xxxxx:3309" user="xxxx"                       password="xxxx">                </writeHost>        </dataHost>

經過測試和比對,發現中間件竟然連接不到數據節點,提示是密碼錯誤,感覺就像資料庫中間件和數據節點沒有做任何配置一樣。

mysql -uxxxx -pxxxx -hxxxx -P3309Warning: Using a password on the command line interface can be insecure.ERROR 1045 (28000): Access denied

這個測試情況讓我大感吃驚,但是問題的方向已經基本明確了,所以和研發同學初步溝通了問題預計的處理策略和時間,就開始處理這個問題了,我逐個在數據節點的從庫伺服器端比對了資料庫帳號情況,發現這個帳號的配置竟然在好幾年前就失效了,通過資料庫帳號的配置發現原來的資料庫帳號只配置了讀寫中間件的IP,但是沒有隻讀中間件的IP。

>>select user,host from mysql.user where user='root';+------+----------------+| user | host           |+------+----------------+| xxxx| [中間件讀寫IP]|| xxxx| localhost      |+------+----------------+6 rows in set (0.00 sec)

明白了這個大坑之後,我開始逐個配置資料庫帳號並逐一在中間件端進行了驗證測試。

等待所有的數據節點都驗證完畢之後,我重啟中間件,只讀中間件就好像喚醒了一般,反應很快,很酸爽。

對於這個問題的原因,讓我還是很感慨,這算是一個遺忘了近3年的問題,這期間因為一直沒有重啟過只讀中間件,所以原本指向的資料庫配置其實是錯誤的,雖然後續做了配置文件的熱加載,但是數據源部分的信息其實一直沒有更新,今天因為業務使用了大查詢導致了中間件節點OOM,接著觸發了高可用機制,自動重啟了中間件,但是重啟之後連接的資料庫權限全部失效。

整個問題的處理過程還是比較快的,尤其是在一種半迷離的狀態下逐步確定問題方向,讓自己確認是資料庫的配置和權限出了問題,這對於我來說著實是一種難以相信的事情,但是恰恰是這個問題,也暴露了很多潛在的風險和隱患。

由此可見,之前聽過的一種簡單粗暴的經驗是有道理的:一個運行多年的服務在3年左右還是需要重啟一下。

關鍵字: