故障分析:一則library cache lock問題處理
編輯手記:library cache lock 大家都並不陌生,在MOS上對該阻塞的一般成因描述為:一般可以理解的是alter table或者alter package/procedure會以X模式持有library cache lock,造成阻塞(444560.1)。但針對具體問題仍要具體分析,今天分享一則因SQL綁定變量出現空值,導致大量子遊標產生並引發library cache lock 的故障,供大家參考借鑒。
請故障現象及影響
某數據庫為Oracle 11.2.0.3.9 RAC Linux 64bit,一天晚上9點左右,業務係統反應緩慢,數據庫曾發現有大量library cache lock等待事件,並伴隨有library cache:mutex X,導致業務係統短暫無法正常提供業務處理
當天起發現數據庫有大量librarycache lock,平均等待有1775ms ,並伴隨有librarycache: mutex X。
觀察ASH報告,等待library cache lock會話在執行SQL如下
對比上周同一天的AWR,這個SQL執行的次數差不多,大概半小時7萬次左右,但在23號的AWR中,該SQL在Order by Version Count出現,Version Count為76(實際上在v$sql中發現有2萬個 不同CHILD_ADDRESS出現),說明該SQL產生過2萬個子遊標。這裏也看到其他SQL High Version,但由於其他SQL執行沒有0pjnn575vchbg頻繁,並不引發library cache lock等待。
該SQL已占用了1GB的共享池空間
結合數據庫版本和環境情形,初步推斷為ACS BUG引發。但在關閉ACS特性後,library cache lock等待事件與子遊標依然存在。
這樣排除了ACS BUG引起後。觀察V$SQL_SHARED_CURSOR中大量BIND_MISMATCH,但BIND_MISMATCH根據Oracle的規則,隻有5,6種不同的可能性,不至於產生2萬個子遊標。進一不查看V$SQL_BIND_CAPTURE發現綁定變量值中,出現異常的varchar2類型,且值為空。結合Bug 8198150 - High Versioncount with bind_mismatch with passing null value to bind (文檔 ID 8198150.8),推斷該SQL綁定變量時輸入了空值,導致產生大量子遊標。在V$SQL_BIND_CAPTURE視圖中表現為VARCHAR2類型(varchar2為Oracle默認類型,null值無類型則為Oracle默認類型)。
應用做調整限製SQL綁定NULL輸入後,SQL正常,無子遊標產生。
-
通過故障的情況相關信息初步推斷為ACS(自適應)bug引起。
-
在關閉ACS特性後觀察,SQL子遊標和librarycache lock等待事件依然存在。
-
進步分析並通過測試確認,原因由於SQL綁定變量輸入null值觸發BUG,導致會產生大量子遊標,引發library cache lock等待。在應用代碼中將null限製後SQL正常
-
應用端嚴格限製非合理的綁定變量時null值輸入。
-
建議給數據庫打上最新PSU,避免觸發各BUG,提高係統健壯性。
最後更新:2017-07-17 17:33:41