1. 程式人生 > 其它 >解析錯誤導致library cache lock+library cache: mutex X

解析錯誤導致library cache lock+library cache: mutex X

1.檢視當前資料庫等待事件

##資料庫等待事件發現大量的library cache lock ##從下圖中的等待事件查詢,基本上可以判定是一條SQL語句導致的,大量回話被1996回話阻塞,1996被回話1354回話阻塞,1354對應的blockding session為空。且所有的回話執行的都是同一條SQL    

2.獲取SQL_TEXT

##通過sql_id無法獲取到sql_text ##分析到這裡根據經驗大概是因為錯誤的SQL文字解析導致的 23:14:57 SQL> select sql_text from v$sql where sql_id='avsaksqw45m7g';
no rows selected   ##mos提供如下方式進行查詢錯誤的SQL文字導致的解析問題sql_id 3.抓取awr報告獲取如下資訊,並分析

##抓取awr報告,從awr報告裡面進一步確定問題

##時間統計模型 ##從這裡可以看到系統主要時間消耗是解析失敗   ##分析到這裡基本上可以確定是因為解析失敗導致的問題故障,這裡我們需要進一步確定問題SQL,因為資料庫正常情況下無法抓取解析失敗的SQL,我們需要設定event事件來輔助解決此類問題。   ##檢視有關解析SQL ##這裡的第一位sql_id和我們從資料查詢到的等待事件顯然不是一個問題,對應sql_id的sql_text無法找到
##說明:這裡的一個排程程序insert,是檢視資料庫效能資訊的監控程式,這裡解析1239次,一次也沒有執行成功顯然是不正常的,對於版本過多的SQL,一次軟解析甚至不如重新執行一次硬解析來的高效,這裡因為資料庫版本是11.2.0.4,因此可以通過修改隱含引數"_CURSOR_OBSOLETE_THRESHOLD",當SQL版本超過這個引數設定後,直接重新硬解析。這裡是問題之外的其他問題,這裡先不做深究。

 4.開啟trace事件進行解析失敗SQL追蹤

ALTER SYSTEM SET EVENTS '10035 trace name context forever, level 1'; ##設定event事件後,資料庫alter日誌開始出現大量硬解析問題SQL,但是單單從SQL語句中感覺不到什麼太大問題

##檢查對應的SQL語句可以正常執行

23:18:10 SQL> select Max(CHECKTIME) from key.M_GLOBALPROCESSINFO; MAX(CHECKTIME) ------------------------------ 2022-05-07 09:26:16  

5.為什麼可以正常執行呢????

##檢查錯誤程式碼輸出--無效的字元??但是從日誌中看解析失敗的語句是正常的啊???為啥呢???? [oracle@oracle11g ~]$ oerr ora 911 00911, 00000, "invalid character" // *Cause: identifiers may not start with any ASCII character other than //         letters and numbers.  $#_ are also allowed after the first //         character.  Identifiers enclosed by doublequotes may contain //         any character other than a doublequote.  Alternative quotes //         (q'#...#') cannot use spaces, tabs, or carriage returns as //         delimiters.  For all other contexts, consult the SQL Language //         Reference Manual. // *Action:     ##測試1執行錯誤的文字 SQL> select * from afadsfa; select * from afadsfa               * ERROR at line 1: ORA-00942: table or view does not exist   ##ALTER日誌對應的資訊 ##從這裡我們發現,SQL語句在資料庫中解析後,並沒有最後的分號?是不是這個問題導致的呢?我們接著測試 PARSE ERROR: ospid=20936, error=942 for statement: select * from tabasfa     ##測試2執行錯誤的文字多出一個分號   SQL> select count(*) from t1;; select count(*) from t1;                        * ERROR at line 1: ORA-00911: invalid character   ##alert日誌對應的資訊 ##這裡alert日誌中輸出的資訊,發現解析文字後面確確實實多了一個分號,和我們上述的情況是一致的。 PARSE ERROR: ospid=24879, error=911 for statement: select count(*) from t1;   問題分析到這裡,基本上可以判斷確確實實是SQL語法有問題,但是開發不可能蠢到一個語句的結束出現兩個分號,因此判斷是plsql程式碼中存在問題,進行了如下測試

 6.問題處理解決

 ##大量無效語句會導致CPU和library cache徵用,最好的處理辦法就是解決應用錯誤的SQL語句,但是作為臨時解決方法,可以通過調整隱含引數減輕不正確解析的影響 ##_cursor_features_enabled隱含引數預設是2,我們需要在這個基礎上加32,需要重新啟動資料庫 SQL> alter system set "_cursor_features_enabled" = 34 scope=spfile; System altered.   ##設定引數並重啟後,解析錯誤的記錄在表sqlerror$中,後續的錯誤的SQL解析成本會降低,不會產生SQL硬解析所有的成本,而是一小部分成本,這樣就減少了資源消耗 ##每條錯誤的SQL只會記錄一條記錄

 

參考MOS:1353015.1