案情描述:
11點20分,DBA接到CPU告警短信,業務資料庫2節點CPU使用率達到100%;
11點22分,DBA登陸業務資料庫進行核查,發現資料庫兩個節點CPU使用率達到100%,并且有library cache lock以及大量cursor: pin S wait on X異常等待事件,資料庫執行查詢緩慢并時常出現挂起的情況。應用人員回報語句緩慢,事務有積壓;
11點24分,DBA對業務資料庫兩個節點執行hang analyze資訊收集。
注意,當我們遭遇到這種情況時,DBA 在進行中的通常過程就是:
首先通過 v$session 、v$session_wait、v$lock 去确定目前資料庫的等待情況,鎖資訊等;
如果資料庫能夠響應,通過ASH報告,可以擷取更直覺的輸出,看看阻塞的情況和情形,然後進行下一步的判斷;
如果資料庫失去響應,或者響應困難,則可以通過 Hang Analyze 進行資訊采集,以便後續分析;
關于資料庫挂起的診斷跟蹤,參考我們之前的文章:
DBA必備技能:資料庫挂起時進行轉儲分析診斷案例。
案情繼續:
11點30分,由于資料庫嚴重挂起,程序積壓嚴重,告知相關部門後,為了盡快恢複業務,重新開機資料庫。
11點35分,資料庫重新開機完畢,CPU資源得到釋放,應用恢複正常。
在實踐中,有時候排查問題可能要遺留到事後,在當時為了盡快恢複業務,使用者就采取了重新開機資料庫的方式。
現在是DBA需要找出原因,防範後續問題的時間了。很多情況下,專業DBA是在這一階段出場,需要找出Root Cause,并且給出防範解決方案。
首先通過ASH記錄的資訊,可以發現,從11月10日11點10分40秒左右,開始出現libaray cache lock以及cursor: pin S wait on X等待事件,這不一定意味着問題,正常解析也會出現:

alter table T_ZT_ORDER add history_record char(1) default ‘0’;
綜合上述分析,造成資料庫CPU高消耗的主要原因是由于開發人員,在生産高峰時段執行了DDL 語句:“Alter table T_ZT_ORDER add history_record char(1) default ‘0’”而引發的。
事實上,自從Oracle 11g開始,當我們在表上增加具有預設值的新字段時,Oracle首先修改資料字典,并不會直接更新所有資料,以減少鎖定。中繼資料的設定在 ecol$ 中:
insert into ecol$(tabobj#, colnum, binarydefval, guard_id) values (:1, :2, :3, :4)
update ecol$ set binaryDefVal = :3 where tabobj# = :1 and colnum = :2
由于增加字段會導緻表結構的變化,統計資訊會被清除:
delete from tab_stats$ where obj#=:1
SQL 需要重新解析,就需要在表上獲得 Library cache lock ,這個鎖定無法獲得,資料庫産生阻塞。
在這個案例中,DDL操作在繁忙時段沒有及時完成,阻塞了2139個會話,就導緻了一次資料庫事故。
那麼如何防範問題呢?不以規矩,不成方圓,後續改進措施建議:
1). 建議開發人員按照操作規範,在進行DDL語句操作前進行相關備案,并且不要在繁忙時段在生産環境執行DDL操作;
2). 建議DBA加強對開發此類DDL操作進行監控。
這就是來自生産的一次故障處理和排查,通過這樣的過程,我們能夠看到,在生産環境中一次小的操作,就可能導緻嚴重的生産故障,一個DDL都不應該草率執行。
原文釋出時間為:2018-05-20
本文作者:墨墨
本文來自雲栖社群合作夥伴“
資料和雲”,了解相關資訊可以關注“
”。