閱讀163 返回首頁    go 微軟 go windows


連續2周多次Hang,隻因應用大量跨節點訪問RAC數據庫!

 一、故障現象

某客戶核心係統數據庫工作日生產時間發現會話積壓,存在大量異常等待事件,部分節點所有聯機日誌組全部處於Active狀態,無法完成數據庫檢查點,數據庫實例處於Hang住的狀態。

 

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

 

環境介紹:

IBM Power8 E880

AIX 7.1 

Oracle  4-nodes RAC(11.2.0.3.15)

 

 二、故障預案

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

 

  1. 部署短信告警,監控Active日誌組個數,當大於四組時告警,以提前發現問題。

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

  3. 緊急停止Hang住的節點,因數據庫集群使用RAC架構,能夠實現高可用,避免單點故障,對實際業務無影響。

 

 三、故障處理過程

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

 

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

 

20170123094159636.jpg

 

 四、資源使用分析

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

 

節點1 CPU使用情況分析:

 

20170123094210449.jpg

 

節點1 IO讀寫情況分析:

 

20170123094230979.jpg

 

節點2 CPU使用情況分析:

 

20170123094238585.jpg

 

節點2 IO讀寫情況分析:

 

20170123094257431.jpg

 

節點3 CPU使用情況分析:

 

20170123094308614.jpg

 

節點3 IO讀寫情況分析:

 

20170123094319167.jpg

 

節點4 CPU使用情況分析:

 

20170123094329881.jpg

 

節點4 IO讀寫情況分析:

 

20170123094338106.jpg

 

 五、故障原因分析

1、檢查點未完成導致數據庫Hang的可能原因:

 

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

 

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

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

  • 賽門鐵克反饋近期SF集群日誌正常,多路徑日誌也未發現異常報錯。

 

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

 

2、System Dump分析:

 

從System Dump輸出日誌文件中發現4個阻塞源頭:

 

20170123094346644.jpg

 

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

 

兩個Sequence阻塞

 

Rcache object=700000b7e8ecf08,      SEQ_LNCH_XXXX_TRIGID

Rcache object=700000bbffdedc0,       SEQ_LNCH_XXXX_TRIGLOGID 

 

20170123094357525.jpg

 

20170123094407408.jpg

                 

可以看到前麵兩個Object都在等待row cache lock,這是一種數據字典的並發爭用引起的鎖。

 

Dump輸出日誌中的sequence如下,Cache size為0。建議與應用溝通為何設置為0,如無特殊場景,RAC環境中設置cache size為1000。

 

20170123094416752.jpg

 

Insert語句 Blocker,等待獲得SEQ

 

20170123094429156.jpg

 

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是一個客戶端發起的的會話。可以看到它當時的信息如下:

 

20170123094441173.jpg

 

非係統級別的Sequence阻塞,會導致相關業務性能急劇下降。

 

Update在等待獲得日誌切換完成   

 

20170123094457820.jpg
 

20170123094509923.jpg
 

20170123094520184.jpg

 

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

 

20170123094531883.jpg

 

3、全局Hanganalyze分析

 

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

 

LGWR進程阻塞了5817個會話,等待日誌切換完成

 

對Hang Analyze結果分析發現,節點2的LGWR阻塞5817個會話。

 

20170123094541426.jpg


20170123094550513.jpg

 

從等待事件上來看,LGWR一直在等待control file sequential read。那麼LGWR為什麼要讀控製文件呢?

 

參考文檔Master Note: Overview of Database ControlFiles (文檔 ID 1493674.1),在日誌切換的時候,LGWR需要去獲取CF隊列,獲取這個隊列之後,就要讀取控製文件。

 

20170123094601732.jpg

 

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

 

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

 

20170123094611431.jpg

20170123094621830.jpg

 

日誌切換之後,有一個“日誌切換檢查點”操作,這個操作由CKPT發起,讓DBWR進程把緩衝區的髒數據寫入磁盤,之後才會把redo logfile的狀態從ACTIVE變成INACTIVE。

 

以下是log switch checkpoint的描述:

 

20170123094631871.jpg

 

通過對Hanganalyze的分析,可以得出一個初步結論,由於DBWR無法把跟ACTIVE redo logfile相關的髒數據寫入磁盤,導致redo logfile狀態一直是ACTIVE。

 

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

 

日誌檢查點沒有完成

 

前麵提到過,日誌切換檢查點會更新係統狀態信息(background checkpoints started和background checkpoints completed),從DBA_his_sysstat曆史表中得到了下列信息,節點2後台檢查點完成信息從10點開始到11點一直沒有更新,而其他節點的檢查點進程完成更新很及時。

 

20170123094642806.jpg

 

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

 

20170123094653462.jpg

 

所有數據庫實例檢查點進程沒有持續未完成的情況發生。

 

異常髒數據,使得CKPT進程異常

 

分析發現,DBW0~DBW6共7個數據庫寫進程狀態正常:

 

20170123094704541.jpg

20170123094735661.jpg

 

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

 

這說明係統認為當前已經沒有髒數據了,它一直在等待其他進程喚醒它工作。這個狀態是正常的。

 

事實上,從System Dump輸出,我們看到數據庫緩衝區中是有存在髒數據隊列:

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

20170123094749695.jpg

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等待事件:

 

20170123094758418.jpg
 

20170123094810606.jpg

 

對應的SQL文本如下:

 

20170123094821634.jpg

20170123094830819.jpg

 

我們可以看到,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索引信息

 

20170123094841152.jpg

 

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

 

(2)該索引同時被節點3和節點4上的應用程序訪問

 

節點3上dump的信息顯示索引IDX_HQMHLCD_RZ_1(object_id:1341208)被訪問過:

 

20170123094851635.jpg

 

節點4上dump的信息顯示索引IDX_HQMHLCD_RZ_1(object_id:1341208)被訪問過:

 

20170123094900423.jpg

 

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

 

5、解決方案:

 

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

  • 重建索引IDX_HQMHLCD_RZ_1,減少碎片,提升索引訪問效率,降低GC等待。

  • 渠道業務相關應用,應做好應用隔離,避免跨庫訪問業務,避免GC等待出現

  • 將隱含參數"_gc_bypass_readers"設置為FALSE(需要應用側充分測試後,方可在生產上實施)

 

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

 

 六、處理結果

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

 

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

 

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

 

保證數據的安全、數據庫的穩定高效運行是DBA團隊的天職。年前大檢查你做好了麼!

 

最後做個小廣告,我們研發的DPM數據庫性能管理平台已經完美支持這些bug預警。

原文發布時間為:2017-01-23

本文來自雲棲社區合作夥伴DBAplus

最後更新:2017-05-15 17:34:04

  上一篇:go  互聯網企業安全高級指南3.8 STRIDE威脅建模
  下一篇:go  京東消息中間件演進之路:三次更迭,八大突破