天天看點

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

 一、故障現象

某客戶核心系統資料庫工作日生産時間發現會話積壓,存在大量異常等待事件,部分節點所有聯機日志組全部處于active狀态,無法完成資料庫檢查點,資料庫執行個體處于hang住的狀态。

第二周幾乎相同時間發生同樣的問題,但由于第一次已經提出預案,是以問題影響得到控制,同時采集到更多分析資訊,最終徹底解決了該問題。

環境介紹:

ibm power8 e880

aix 7.1 

oracle  4-nodes rac(11.2.0.3.15)

 二、故障預案

第一次故障發生後,提出以下預案并在第二次故障發生時,提前發現問題,介入診斷,業務無影響。

部署短信告警,監控active日志組個數,當大于四組時告警,以提前發現問題。

第一時間介入後抓取現場,添加可用日志組以延緩故障發生時間,給現場診斷留出時間。

緊急停止hang住的節點,因資料庫叢集使用rac架構,能夠實作高可用,避免單點故障,對實際業務無影響。

 三、故障處理過程

為確定能夠對故障進行事後分析,徹底定位和解決問題,對生産庫做hanganalyze分析和進行采集system dump,但該系統非常繁忙,采集system dump時間需60-90分鐘,是以為控制業務影響範圍,在做10分鐘左右dump之後,緊急停止dump,并優先停止節點2,以恢複資料庫,至11點48分,資料庫完全恢複,正常提供對外服務。

鑒于本次故障比較複雜,我們用思維導圖的形式将故障診斷分析過程簡化,友善你的了解。如果你有更好的分析思路,歡迎文末評論!

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

 四、資源使用分析

通過對比,我們可以發現,周五的資料庫負載基本與平時相差不多,整體均在正常狀态。

節點1 cpu使用情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點1 io讀寫情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點2 cpu使用情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點2 io讀寫情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點3 cpu使用情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點3 io讀寫情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點4 cpu使用情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點4 io讀寫情況分析:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

 五、故障原因分析

1、檢查點未完成導緻資料庫hang的可能原因:

首先懷疑歸檔目錄出現問題導緻無法寫入歸檔日志,采取以下措施進行排查:

歸檔目錄空間足夠,不存在空間問題。

對歸檔目錄進行dd操作,對目錄進行touch檔案的操作,不存在無法讀寫問題。

賽門鐵克回報近期sf叢集日志正常,多路徑日志也未發現異常報錯。

正常排查未發現問題的情況下,隻能從當時抓取dump中進行分析,以找到問題根源。

2、system dump分析:

從system dump輸出日志檔案中發現4個阻塞源頭:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

從中可以看到總共有四個阻塞源頭,然後一一查找源頭。

兩個sequence阻塞

rcache object=700000b7e8ecf08,      seq_lnch_xxxx_trigid

rcache object=700000bbffdedc0,       seq_lnch_xxxx_triglogid 

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

可以看到前面兩個object都在等待row cache lock,這是一種資料字典的并發争用引起的鎖。

dump輸出日志中的sequence如下,cache size為0。建議與應用溝通為何設定為0,如無特殊場景,rac環境中設定cache size為1000。

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

insert語句 blocker,等待獲得seq

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

insert into qtkb_xxxx_planral(rsrv_str2,……) values (:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:1         1,:12,:13,:14,:15,:16,:17,:1

這個blocker是一個用戶端發起的的會話。可以看到它當時的資訊如下:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

非系統級别的sequence阻塞,會導緻相關業務性能急劇下降。

update在等待獲得日志切換完成   

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

可以看到這個會話被inst: 2, sid: 5376阻塞。5376就是節點2的lgwr程序,他一直在等待log file switch(checkpoint incomplete)完成。

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

3、全局hanganalyze分析

在12月16日故障發生過程中,已對資料庫2節點做全局hanganalyze分析。發現有兩個blocker分别阻塞5817個會話和3694個會話,接下來依次分析。

lgwr程序阻塞了5817個會話,等待日志切換完成

對hang analyze結果分析發現,節點2的lgwr阻塞5817個會話。

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

從等待事件上來看,lgwr一直在等待control file sequential read。那麼lgwr為什麼要讀控制檔案呢?

參考文檔master note: overview of database controlfiles (文檔 id 1493674.1),在日志切換的時候,lgwr需要去擷取cf隊列,擷取這個隊列之後,就要讀取控制檔案。

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

update語句阻塞了3600個會話,等待日志切換完成

dml語句:update,然後它們的阻塞會話在等待log file switch(checkpoint incomplete)。

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

日志切換之後,有一個“日志切換檢查點”操作,這個操作由ckpt發起,讓dbwr程序把緩沖區的髒資料寫入磁盤,之後才會把redo logfile的狀态從active變成inactive。

以下是log switch checkpoint的描述:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

通過對hanganalyze的分析,可以得出一個初步結論,由于dbwr無法把跟active redo logfile相關的髒資料寫入磁盤,導緻redo logfile狀态一直是active。

4、深入分析日志切換檢查點

日志檢查點沒有完成

前面提到過,日志切換檢查點會更新系統狀态資訊(background checkpoints started和background checkpoints completed),從dba_his_sysstat曆史表中得到了下列資訊,節點2背景檢查點完成資訊從10點開始到11點一直沒有更新,而其他節點的檢查點程序完成更新很及時。

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

正常情況下(12月26日),檢查點完成資訊如下:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

所有資料庫執行個體檢查點程序沒有持續未完成的情況發生。

異常髒資料,使得ckpt程序異常

分析發現,dbw0~dbw6共7個資料庫寫程序狀态正常:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

可以看到dbwr當時的等待事件是'rdbms ipc message',也就是空閑等待。

這說明系統認為目前已經沒有髒資料了,它一直在等待其他程序喚醒它工作。這個狀态是正常的。

事實上,從system dump輸出,我們看到資料庫緩沖區中是有存在髒資料隊列:

ckptq: [null] fileq: [0x7000009cf6f61d0,0x7000004cfa39a60] objq: [0x7000003ffa24818,0x7000006d77eeda8] objaq: [0x70000043f871938,0x7000006d77eedb8]

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

obj:1341208  objn:141351

這個髒塊上的對象是一個index,對應的對象名稱為idx_hqmhlcd_rz_1 (對應的表為:  udp_prod31.qfchl_xxxxaction_log)。 

髒資料塊上索引對應的語句

進一步從日志分析發現,索引idx_hqmhlcd_rz_1相關的業務sql在資料庫故障發生前存在gc cr multiblock request等待事件和gc current request等待事件:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

對應的sql文本如下:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!
連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

我們可以看到,select語句裡顯性的指定了使用這個索引idx_hqmhlcd_rz_1,而每個insert語句都會對索引進行更新。

進而推導,是否是idx_hqmhlcd_rz_1及相關語句觸發了bug,導緻的ckpt程序異常呢?

進一步從mos去查證,bug 16344544與此極為相符。

跨節點業務通路導緻的bug

通過以上分析,我們推斷,表udp_prod31.qfchl_hqmhlcd_logrz對應的insert語句和select語句跨節點通路觸發bug 16344544,導緻checkpoint檢查點程序無法讓dbwr程序将髒資料寫入磁盤,造成了日志組狀态持續為active,無法變成inactive正常狀态。

該bug證明影響的資料庫版本為11.2.0.3/11.2.0.4,官方文檔顯示12.1以下版本都可能遭遇。詳情通路mos文章:bug 16344544 deadlock and hang possible in rac env between 'gc current request' and  'gc cr multi block request'。

但據官方文檔記載該bug暫無更新檔,隻有一個workround規避問題:修改隐含參數"_gc_bypass_readers"為false。

更多idx_xxxxhuod_rz_1索引資訊

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

(1)該索引為本地分區索引,從2013年系統上線以來,一直沒有做過重組,大小已經很大,存在大量碎片。

(2)該索引同時被節點3和節點4上的應用程式通路

節點3上dump的資訊顯示索引idx_hqmhlcd_rz_1(object_id:1341208)被通路過:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

節點4上dump的資訊顯示索引idx_hqmhlcd_rz_1(object_id:1341208)被通路過:

連續2周多次Hang,隻因應用大量跨節點通路RAC資料庫!

至此,我們基本判定觸發bug。要規避這樣的問題,就要消除上面兩個因素。

5、解決方案:

該問題的解決方案有3個:

重建索引idx_hqmhlcd_rz_1,減少碎片,提升索引通路效率,降低gc等待。

管道業務相關應用,應做好應用隔離,避免跨庫通路業務,避免gc等待出現

将隐含參數"_gc_bypass_readers"設定為false(需要應用側充分測試後,方可在生産上實施)

考慮到方案的可實施性,先進行索引重建,然後逐漸完成應用通路隔離。

 六、處理結果

在應用側配合完成索引重建及應用隔離後,問題徹底解決。

此問題診斷分析、處理及跟蹤長達3周時間,其間各類oracle服務公司紛沓而至,問題指向千奇百怪,靠着新炬專家團隊通力合作,深入、細緻、理性的分析,最終推導,并完美解決!

最終的問題分析會上,客戶上司評論:“所有廠商的人應該學習新炬專家這種抽絲剝繭的故障問題分析方法!”

保證資料的安全、資料庫的穩定高效運作是dba團隊的天職。年前大檢查你做好了麼!

最後做個小廣告,我們研發的dpm資料庫性能管理平台已經完美支援這些bug預警。

原文釋出時間為:2017-01-23

本文來自雲栖社群合作夥伴dbaplus