TiDB故障處理之讓人迷惑的Region is Unavailable

balahoho發表於2023-12-28

背景

最近某叢集擴容了一批物理機,其中 TiKV 節點有6臺機器12個例項,同時調整了 label 設定增加了一層機櫃級容災。因為前期做了比較充分的準備工作,到了變更視窗只等著執行scale-out就行,操作過程也很順利,很快就把所有節點都擴進去了,檢查完各例項的執行狀態,確保region已經開始正常排程,就放心去睡覺了(半夜變更,結束時凌晨1點左右)。

第二天一大早還在上班路上,業務方反饋資料庫有部分SQL報錯Region is Unavailable,懷疑新擴容的 TiKV 節點出了問題,火速趕到公司開始排查。

此時內心os,打工人1024不加班的小小心願要破滅了。。🤣

故障現象

業務方反饋的報錯資訊如下:

Weixin Image_20231030211323.png

其實Region is Unavailable不算什麼疑難雜症,從過往經驗來判斷基本是 TiKV 節點的原因,從字面意思上看就是region在某段時間內不可用,可能的因素有:

  • region leader在排程中,或者無法選舉出leader(會有內部backoff)
  • tikv例項繁忙被限流,同步可能會有 TiKV server is busy報錯
  • tikv例項故障掛掉了,同步可能會有 TiKV server is timeout報錯
  • 其他tikv未知問題或bug等

前三種基本能覆蓋90%以上的場景,所以我一開始還是從tikv著手排查。

但是讓人迷惑的是,各種分析下來最後發現和tikv沒有關係,這就是最有意思的點。🙈

好戲開始。

排查過程

首先檢查前一天晚上擴容的12個tikv例項執行狀態,分析監控和日誌並未發現有異常現象,無重啟,各節點負載也很低不存在效能瓶頸。

接著懷疑是偶發性報錯,因為region還處於排程中(到這裡感覺到了排程不太正常,比預期中的要慢),偶發性還是有可能的,另外透過監控皮膚failed query OPM發現tikv:9005報錯碼只是零星出現,也不排除這種可能性。

驗證方式:從dashboard日誌搜尋中找出具體報錯的SQL,直接用報錯碼搜尋即可:

企業微信截圖_20231024115854.png

把SQL拿出來嘗試手動執行,發現也報同樣的錯,多次執行效果一樣。於是懷疑這張表的region有副本丟失,打算用show table regions看下這張表的region分佈,發現了一個奇怪的報錯:

企業微信截圖_20231024114525.png

從報錯資訊看,在執行show table regions的時候tidb server去請求了pd的一個API,這個API是作用是查詢region id為xxx的詳細資訊,但是無法訪問pd節點。跟著報錯資訊,我去檢查了這個pd節點的狀態,發現沒有任何異常,服務正常執行未發生過重啟。

接著我進去pd-ctl用報錯的region id查詢region資訊,也能夠正常返回,確認pd節點正常。

退出客戶端,手動執行curl API,報錯依舊,telnet測試報錯pd例項,無法連線,然後把三個pd都telnet了一遍,發現只有這一個pd無法訪問,異常詭異,初步懷疑網路有問題。

但是擴容前網路環境都檢查過都是聯通狀態,而且都在同一個網段中,不應該有網路故障。

接著轉頭去看那個連線不上的pd節點日誌,跟蹤了一段時間發現絕大部分都是region排程的資訊,但是一點一點翻發現中間偶爾出現operator timeout的字樣,認真把日誌讀了幾遍總算看清楚了它說的啥,大意就是在兩個store之間mv peer超時(應該是10min)失敗了:

企業微信截圖_20231024114813.png

期間並沒有發現pd自身執行異常問題,回想起前面的排程慢,猜測應該和這個現象有關,貌似和Region is Unavailable有一點點沾邊了,但還不能完全解釋過去,繼續懷疑網路。

吐槽:給個WARN日誌是不是好點

接著命令列登入原有的tidb例項,再次執行報錯的SQL和show table regions,神奇的事情發生了,均能夠正常返回。再換另一臺新擴的tidb節點執行,報錯依舊。

到這裡基本判定是新擴進來的tidb例項有問題,此時距離故障出現超過2小時,業務方開始著急了,無奈之下只能把新擴的tidb例項從負載均衡中剔除臨時繞過,詳細原因進一步排查。

重新梳理了一下思路,我們都知道正常select查詢和show table regions都需要從pd獲取表的region分佈資訊,這個請求是從被連線的tidb server上發起的,現在奇怪的地方是新擴容的tidb server無法訪問pd,原有的可以訪問,那說明極有可能是新節點被限制訪問了。

登入pd節點檢視防火牆狀態,是關閉狀態,進一步檢查發現iptables服務開啟,檢視配置規則後虎軀一震:

企業微信截圖_20231024120329.png

這簡直是在不亞於在程式碼裡下毒啊,所有tidb叢集相關的通訊埠全都顯式地做了限制,只允許原叢集的5臺機器訪問,做了也不算啥,偏偏有的做有的不做,這就有點坑了。。。而且這臺機器上還部署了2個tikv例項,那前面operator timeout也說的通了。

至此覆盤一下問題:原叢集某些節點設定iptables規則,限制叢集外的節點無法與tidb內部服務通訊,新擴容的機器並不知道有這個限制,導致新擴容的tidb server無法從pd獲取region資訊,連線到新tidb server的會話無法讀到region,丟擲Region is Unavailable報錯。同時該節點上的tikv例項無法與新擴容的tikv例項通訊,導致region排程受影響,直觀感受是排程非常慢。

回過頭再看,還好故障比較簡答,1024算是保住了。

解決方案

經過各方溝通,得知iptables是為了解決早期某安全漏掃問題設定,現在也沒辦法直接關掉。那麼解決辦法就只有一條路,把新擴容的所有機器ip都加到iptables白名單裡即可,順便也檢查了原有的5臺機器iptables設定情況,該加的都加上。

vi /etc/iptables.rules
systemctl restart iptables

調整完畢後重新用客戶端登入新擴容的tidb server執行SQL,發現一切都恢復正常了。

同時region遷移也明顯加速,修改前:

企業微信截圖_20231030225918.png

修改後:

企業微信截圖_20231024113845.png

企業微信截圖_20231024115104.png

企業微信截圖_20231024115135.png

總結

看似一個簡單的操作就解決了問題,實際背後隱藏了很多工作在裡面,碰到問題不可怕,重要的是要有清晰的思路,綜合運用自己的經驗。

就像有個故事裡說的,知道在哪畫線比會畫線更值錢,troubleshooting就是核心競爭力。

作者介紹:hey-hoho,來自神州數碼鈦合金戰隊,是一支致力於為企業提供分散式資料庫TiDB整體解決方案的專業技術團隊。團隊成員擁有豐富的資料庫從業背景,全部擁有TiDB高階資格證書,並活躍於TiDB開源社群,是官方認證合作伙伴。目前已為10+客戶提供了專業的TiDB交付服務,涵蓋金融、證券、物流、電力、政府、零售等重點行業。

本文首發渠道:TiDB社群專欄 https://tidb.net/blog/8f7e13dc

相關文章