解析錯誤導致library cache lock+library cache: mutex X
阿新 • • 發佈:2022-05-10
1.檢視當前資料庫等待事件
##資料庫等待事件發現大量的library cache lock ##從下圖中的等待事件查詢,基本上可以判定是一條SQL語句導致的,大量回話被1996回話阻塞,1996被回話1354回話阻塞,1354對應的blockding session為空。且所有的回話執行的都是同一條SQL2.獲取SQL_TEXT
##通過sql_id無法獲取到sql_text ##分析到這裡根據經驗大概是因為錯誤的SQL文字解析導致的 23:14:57 SQL> select sql_text from v$sql where sql_id='avsaksqw45m7g';##抓取awr報告,從awr報告裡面進一步確定問題
##時間統計模型 ##從這裡可以看到系統主要時間消耗是解析失敗 ##分析到這裡基本上可以確定是因為解析失敗導致的問題故障,這裡我們需要進一步確定問題SQL,因為資料庫正常情況下無法抓取解析失敗的SQL,我們需要設定event事件來輔助解決此類問題。 ##檢視有關解析SQL ##這裡的第一位sql_id和我們從資料查詢到的等待事件顯然不是一個問題,對應sql_id的sql_text無法找到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:165.為什麼可以正常執行呢????
##檢查錯誤程式碼輸出--無效的字元??但是從日誌中看解析失敗的語句是正常的啊???為啥呢???? [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