經典故障分析 - ASSM引發的索引爭用與 enq HW -contention 等待事件
作者介紹:
孫加鵬 雲和恩墨技術顧問
六年Oracle技術顧問經驗,所服務的行業包括電信運營商、金融業、製造業等。
擅長Oracle的故障診斷、高可用架構、升級遷移等。目前主要服務於上海金融類客戶。
2017年07月24日11:58左右,客戶核心數據庫出現大量活動會話,導致數據庫負載急劇加大,從而導致業務出現延時,DBA通過查看SESSION信息發現有大量的“enq: HW - contention”等待事件。
下麵是詳細的故障分析診斷過程,以及詳細的解決方案描述。
ENMODB數據庫出現大量活動會話,數據庫負載急劇加大,通過V$SESSION能看到大量enq:HW contention的活動會話信息,客戶緊急采集了ASH信息,方便後期故障分析。
從AWR和ASH兩個維度來分析此故障,先整體後局部,首先從AWR分析入手。
1、AWR分析
首先看一下故障時間段的AWR報告:
半小時的采樣時間,DB Time 215mins,其中等待時間“enq: HW - contention”占據近36%,為TOP 10 events中最主要的非空閑等待事件。
等待事件“enq: HW - contention”的解釋:
The HW enqueue is used to manage the allocation of space beyond the high water mark of a segment. The high water mark of a segment is the boundary between used and unused space in that segment. If contention is occurring for "enq: HW - contention" it is possible that automatic extension is occuring to allow the extra data to be stored since the High Water Mark has been reached. Frequent allocation of extents,reclaiming chunks,and sometimes poor I/O performance may be causing contention for the LOB segments high water mark.
The HW enqueue is used to serialize the allocation of space beyond the high water mark of a segment. If lots of data is being added to an object concurrently, then multiple processes may be trying to allocate space above the high water mark at the same time, leading to contention.
簡而言之,HW鎖是在分配高水位線以上的空閑空間時,多個進程同時為了分配高水位線上空閑空間而修改HWM,修改HWM需要持有HW鎖,該鎖又屬於排他鎖(mode=6)。
如果大量數據被並發插入某個對象時,那多個進程可能會試圖在高水位線以上同時申請可用空間,大並發的申請HW鎖,從而導致HW enqueue爭用。HW – contention等待事件的P1,P2,P3參數參考下表;
發現這個時間段確實有大量的INSERT操作,半小時采用中,該SQL執行了約近24w次。
下一步看看HW競爭是在表段還是在索引段上?
大量的物理讀/物理寫請求也都發生在表TAB_ENMO的索引上。這裏可以猜測HW競爭可能不在表上,而在這幾個索引上麵,IO讀寫請求非常高。
2、ASH分析
通過客戶采集的ASH分析發現,等待事件“enq: HW - contention”是從07月24日11:57:12秒左右開始的,此類session全部被session id為1191的會話阻塞。
查看1191會話信息,發現11:57:12的時候沒有被任何會話阻塞(NOT IN WAIT),Session狀態是ON CPU:
這個時間點11:57:12的時候會話1191在執行以下的INSERT操作,這個就是源頭,並且這個SQL一直在執行。
INSERT操作從11:57:11開始,後續該會話一直都是HW競爭,並且跟其他SESSION爭相持有HW鎖。
這個時間點大量的SESSION都在持續申請HW鎖,因此都在相互blocking sessions。從p1,p2,p3參數中發現P3值並不代表爭用塊的RDBA(data block address)(36730這個值太小了,這是為啥?先思考下)。
既然P3找不到RDBA,那就從ash中字段CURRENT_FILE#和CURRENT_BLOCK#上尋找爭用塊:
發現所有的HW競爭都發生在索引IDX_TAB_ENMO_SEQ上,該索引就是表TAB_ENMO上的索引,HW競爭的SQL語句也是上麵AWR中發現的SQL。
既然是大並發持有HW鎖,多個進程是持續不斷的申請HW鎖,說明不斷的發現free space不足,一般ASSM管理都是一次性分配多個extent,根據對象大小一個extent下麵又會有多個block。除非指定storage參數next size 大小:
表空間ENMO_DATA是ASSM(自動段空間管理),並且是本地管理表空間,獲取表空間的定義語句:
表空間自動擴展NEXT SIZE 100M。段管理方式使用自動段空間管理(ASSM)。這裏有個地方值得關注下,這個表空間屬於bigfile tablespace,這就是為什麼通過等待事件中的p1,p2,p3參數無法精確定位到具體發生爭用的block了。
具體可以參考Mos文檔:ID 2098543.1。
因此上麵的P3參數指的datafile中的block number,其實就是這個索引段的段頭(segment header)所在的block。
所以HW競爭還是發生在索引的段頭上,因為段頭會記錄HWM信息,進程修改HWM就必須要持有HW鎖,並修改索引段頭上的HWM。所以P3=36730是準確的,隻是這個P3參數代表是bigfile tablespace上的block number,dump出file_id=6 block_id=36730的塊,可以看出就是索引IDX_TAB_ENMO_SEQ的Segment header。
現在問題基本明朗了,所有的爭用都發生在索引的Segment Header上麵,進程為了需要更多的空間(unformatted),通過持有HW鎖來修改高水位線(HWM),大量的進程並發從而導致HW鎖上的競爭。
那既然是ASSM管理,為何新的extent分配的時候還會出現HWM上的競爭呢?不都是bitmap管理了嗎?比之前freelist管理要好很多啊,看看這個索引的DDL語句:
索引的stroage參數中NETX=1M,即每次分配空間以每次1M大小來分配,8k塊大小即相當於每次分配
128個blocks。難道是客戶創建索引的時候指定extent分配大小?問題是不是發生在這個NEXT 1M上麵呢?
顯然不是的,自動段管理表空間(ASSM)下這個NEXT擴展字句應該是不生效的,不會按照這樣來初始化extent的。
可以檢查下索引的extent分布,看看extent下麵包含多少個blocks。
上麵信息可以看出索引的extent並不是隻有128個塊,跟ASSM的extent分配機製匹配的,segment後期會按照64M的大小分配extent,即每個extent有64*1024/8=8192個block。
7月24日故障之後幾天,又不間斷的出過2~3次同樣的故障,那為何不間斷的會發生這種故障?索引真的有這麼需要unformatted空間嗎?表上有大量的INSERT操作的同時也需要維護索引,同時索引也會進行分裂,不論是leaf node split還是branch node split,都需要新塊來滿足分裂,實驗證明索引分裂隻請求unformatted的塊,未滿塊或空閑塊都不會使用。下麵來看看索引上unformatted 塊的使用情況,這個show_space存儲過程來自TOM大師的分享:
同時12點12分左右又出現一次HW競爭嚴重的情況,導致AAS飆高,係統負載急劇升高。因此每次出現HW競爭都是因為Unformatted Blocks不夠用的時候,多個進程修改索引段頭的HWM的時候持有HW鎖。
所以問題原因主要是多個進程同時修改索引段頭上的HWM而導致的爭用,針對這種問題一般采用HASH分區索引,通過將索引改造成HASH分區索引來緩解索引段頭的爭用,這樣從原來的在單個段頭修改HWM,到現在的在多個分區索引的段頭上修改HWM。將原先索引從一個L3位圖管理塊,到多個L3層位圖管理塊。
先看一下ASSM的extent三層位圖管理結構:
整個位圖三級位圖結構是一個樹形結構,L3往往代表的就是Segment Header,L3中記錄了所包含的所有L2位圖塊的地址,L2位圖塊中又包含了所屬L1位圖塊地址。L1位圖塊中記錄了具體數據塊的地址和使用情況。
L3,L2,L1三層結構均以樹形結構,一對多的關係。
下麵我們來dump出索引的段頭(Segment Header)信息。
索引目前已經有2323個extents,現在的高水位線在extent_id 2322 block_id 8192位置。”L2 Hint for inserts”這表名INSERT插入的記錄從這個L2(後麵跟的是bigfile的block_id)開始。
Dump出這個L2位圖塊:
如上,這個L2中包含有1007個L1,free L1有77個,L1共有三個狀態值,分別為Free 1,Free 3和Free 5,3和5都代表該L1下麵有空塊。
ASSM管理表空間的Table Block的狀態有7種,分別是:
0 = unformatted
1 = logically full (per pctfree)
2 = 0-25% free
3 = 25-50% free
4 = 50%-75% free
5= 75-100% free
對於Block的DUMP有興趣的可以研究研究。
問題原因主要是多個進程同時修改索引段頭上的HWM而導致的爭用,針對這種問題一般采用HASH分區索引,通過將索引改造成HASH分區索引來緩解索引段頭的爭用,這樣從原來的在單個段頭修改HWM,到現在的在多個分區索引的段頭上修改HWM。
引入思考,當初設計表的時候,從業務角度出發,知道這是一個業務流水表,流水表的特點就是大量的DML操作,特別是INSERT操作的存在,表級別做了分區設計,索引上未考慮到位采用了普通索引,導致後期性能下降和故障發生。因此好的數據庫結構設計是有多麼重要。
原文發布時間為:2017-09-05
本文作者:孫加鵬
本文來自雲棲社區合作夥伴“數據和雲”,了解相關信息可以關注“數據和雲”微信公眾號
最後更新:2017-09-05 09:02:50
上一篇:
Changing the Way of Continuous Delivery with Docker (Part 2)
下一篇:
國際頂會 SIGCOMM,我們來了!
Java 後台框架源碼 springmvc spring mybatis SSM 有websocket即時通訊 代碼生成器
直擊阿裏雙11神秘技術:PB級大規模文件分發係統“蜻蜓”
Storm專題一、Storm DRPC 分布式計算
九度題目1364:v字仇殺隊
(轉載)WCHAR與CHAR的轉換
專家對VC與C#的比較
2013年2月 Web 編程語言就業趨勢
阿裏雲虛擬主機:如何上傳壓縮文件,如何解壓縮?
《Linux From Scratch》第三部分:構建LFS係統 第六章:安裝基本的係統軟件- 6.4. 進入 Chroot 環境
態勢感知將DDOS扼殺在搖籃中:涉及數千台PostgreSQL服務器