Library Cache 診斷:Lock, Pin 以及 Load Lock (文件 ID 1548524.1)

你好我是李白發表於2020-03-04

文件內容


 


 


 


 


 


 


 


 


 


 


 


 


 



 

適用於 :

Oracle Database - Personal Edition - 版本 8.1.7.4 和更高版本
Oracle Database - Standard Edition -
版本 8.1.7.4 和更高版本
Oracle Database - Enterprise Edition -
版本 8.1.7.4 和更高版本
本文件所含資訊適用於所有平臺

用途

下面文件中將提供關於 Library cache lock, Library cache pin 與 Library cache load lock 等待事件的一些簡明的知識。

排錯步驟

 

  • 什麼是 "Library cache lock" ?

這個事件控制對 library cache 的併發使用。 它獲取一個物件控制程式碼(object handle)上的鎖,從而:

    • 一個使用者可以防止其它使用者訪問同一個物件。
    • 這個使用者可以長時間地維護一個依賴物件(例如,其它使用者不能更改這個物件)。

定位 library cache 中的一個物件同樣也需要這個鎖。
在解析或編譯 SQL 或 PL/SQL 語句期間,我們需要獲得被引用的資料庫物件(表,檢視,過程,函式,包,包體,觸發器,索引,聚簇,同義詞)的 library cache lock;這個鎖在解析與編譯結束時會被釋放。

cursor(SQL 與 PL/SQL 區),管道(pipes)和其它的瞬時(transient)物件不使用這個鎖。
Library cache lock 上的死鎖不會被自動檢測到,對其的操作是同步進行的。

引數:

    • handle address
           
      物件地址
    • lock address
           
      鎖地址。它與 latch 與 enqueue 不同,它是一個 State Object。
    • Mode
           
      申請鎖的級別
    • Namespace
           
      物件使用的 namespace, 取自於 V$DB_OBJECT_CACHE。
  • 什麼是 "Library cache pin" ?

這個事件管理 library cache 併發。Pin 住一個物件會使它使用的 heap 被載入到記憶體中。如果一個使用者想要修改或檢查這個物件,它必須在獲得 lock 之後再取得一個 pin。Pin 可以用 NULL, SHARE, EXCLUSIVE 模式獲得,並且可以看做是一種特殊的 lock。等待"library cache pin"意味著這個 PIN 正被某個其它 session 以不相容的模式持有。

訪問當前被快取到 library cache 中的資料庫物件(表,檢視,過程,函式,包,包體,觸發器,索引,聚簇,同義詞)的時候需要獲得 library cache pin; 在 library cache 中,資料庫物件被快取成兩部分:控制程式碼(handle)和物件(object); 這個鎖(pin)只有當"object"部分被快取的時候才會被持有。

Library cache pin 上的死鎖不會被自動檢測到,對其的操作是同步進行的。

注意:在10g以後,"library cache pin"已經被 mutex 取代。
參見:
Document 1298015.1  WAITEVENT: "cursor: pin S wait on X" Reference Note

 

  • 為什麼需要這兩種不同型別的鎖 ?

Lock 與 pin 都用於訪問在 library cache 中的物件。Lock 管理不同程式間的併發,pin 則管理緩衝區的一致性。為了訪問一個物件,程式必須首先鎖定(lock)這個物件的控制程式碼(handle),然後它自己 pin 住物件的記憶體堆。

Lock 與 pin 請求會一直等待直到獲得為止,這是一個引起爭用的可能的原因,因為它沒有 NOWAIT 請求模式。

透過獲得一個在物件控制程式碼上的鎖,一個程式能防止其它程式訪問這個物件,甚至不可以檢視它的型別。它還能在維護物件依賴關係的同時不阻止其它程式訪問這個物件。獲取一個 lock 同樣也是在快取中查詢物件的唯一途徑。查詢並鎖住物件是在一個操作中完成的。

如果一個程式想檢查或修改一個物件,那麼它必須獲得一個在這個物件上的 pin (獲得了在控制程式碼上的鎖之後)。Pin這個動作會將相應物件的資訊載入到記憶體,如果之前沒有的話,同時還能確保這些資訊保留在記憶體直到 pin 被釋放。

Oracle 在分析/編譯 Package/Procedure/Function/View 時需要 Library Cache Lock 和 Library Cache Pin。這是為了確保在分析/編譯期間, 沒有其它人可以對這些物件的定義進行改變,或者刪除、重建這個物件。

當一個 SQL 語句被一個 session 硬解析時,這個 session 需要獲得一個 library cache lock 以便阻止其它 session 去訪問或修改同一個物件。如果這個事件等待很長時間。這表明可能 shared pool 過小或經常發生物件被 flush 出去的清醒。還有,這表明資料庫物件被經常修改。

除了硬解析,如果一個 session 要更改被 SQL 語句引用的物件的定義或對其做任何更改,就必須獲得一個 library cache lock 和 library cache pin。需要 Pin 的原因是需要載入資料字典資訊到記憶體中來修改這個物件。

Document 34579.1  WAITEVENT: "library cache pin" Reference Note

  • 減少 Library Cache 競爭的一般建議

下邊會介紹一下解決不同競爭的不同的方法。但是,很多時候這些現象都是由於 SQL 語句的版本數造成的。如果您看到了任何跟 library cache 相關的競爭,應該立刻檢查 AWR Report 確保沒有版本數很高(比如幾百)的 SQL 語句。



如果有的話請參見以下文件解決:

Document 296377.1  Troubleshooting: High Version Count Issues

  • 如何降低 library cache lock 等待

我們首先要確認的是 library cache 的競爭是整個系統層面的還是隻發生在某個或某些 SQL 語句上。這個"library cache lock"是被一個特定的 SQL 持有很長的時間嗎?或者總是在等待某個特定的物件?還是說這個鎖在短時間內被請求的次數很多從而造成的競爭?

如果問題是在整個系統層面發生的,一般來說是由於 shared pool 太小或 SQL 語句不共享造成的。一些解決競爭的方法:

    • 增大 shared pool 從而減少 reload 的次數,這是因為 shared pool 過小會造成獲取鎖的時間加長。
    • 透過將 cursor_sharing 設定為 similar 或 force 來使 SQL 語句共享。
            需要小心的是這樣做可能會改變SQL的執行計劃,所以做之前需要做完整的測試。
    • 在系統不繁忙的時候做統計資訊的收集或其它維護作業,從而降低無效化(invalidation)的次數。

Oracle Performance Diagnostic Guide (OPDG) 針對這個等待事件提供了一些非常有用的診斷場景:



Oracle Performance Diagnostic Guide (OPDG)
可以在以下文件中下載:

Document 390374.1  Oracle Performance Diagnostic Guide (OPDG)

如果您發現是某條或某些SQL產生的問題,那麼需要檢查為什麼它持有鎖的時間會那麼長。
以下文件可以用來找到誰在持有鎖以及在哪個物件上:

Document 122793.1  How to Find which Session is Holding a Particular Library Cache Lock

 

    • 如何降低 library cache pin 等待

如果"library cache pin"等待的時間很長那麼很重要的一點就是判斷是隻有一兩個 process 在等待還是有很多的 process 都在等待。

      • 如果說只是一兩個 process 被另一個 process 阻塞的話,那麼需要檢查持有這個 pin 的 process 為什麼這麼長時間不釋放。
      • 如果說等待是大範圍的那麼說明 shared pool 需要最佳化。
               
               

Document 62143.1  Troubleshooting: Tuning the Shared Pool and Tuning Library Cache Latch Contention

 

  • 什麼是 Library cache load lock?

Session 嘗試去查詢資料物件上的 load lock,以便能載入這個物件。

Load lock 一定是以排它模式獲得,以便沒有其它程式可以載入同一個物件。如果無法獲得 load lock,那麼 session 將等待這個事件,直到其變為可用狀態。

等待時間: 3秒(PMON 會等待1秒)

引數:

    • object address 
           
      物件的地址
    • lock address
           
      鎖的地址
  • 如何減少 Library cache load lock

如果一個物件不在記憶體中,那麼我們不能對其申請 library cache lock。
因此,需要將這個物件載入到記憶體中。
然後,session 嘗試找到資料庫物件的 load lock,以便它能載入這個物件。
為了阻止多程式同時請求載入同一個物件,其它同樣請求的 session 將等待 library cache load lock 因為這個物件正在被載入到記憶體中。

等待 library cache load lock 是由於物件在記憶體中是不存在的。 
Library cache 中的物件不存在,是由於 shared pool 過小引起的頻繁重新裝載,或太多的硬解析緣於不共享的 SQL。

避免這種等待的通常建議:

    • 增加 shared pool(避免 reload).
    • 增加 session cached cursors(避免 cursor 被刷出 shared pool)
      • 設定 cursor_sharing 為 force(減少硬解析)。---可能改變執行計劃與查詢的效能,所以要作充分的測試。

Document:94036.1  Init.ora Parameter "CURSOR_SHARING" Reference Note

  • Library cache pin library load lock 是什麼關係

Library cache pin 和 load lock 可能出現在對 PL/SQL, views, types 等的編譯與重編譯期間。這種編譯總是顯式的(比如應用安裝,升級,打補丁)。但是物件重編譯也可能發生在物件失效期間。

在處理那些“奇怪“的 library cache pin 和 load lock 等待時,我們需要檢查為什麼物件失效了。很有可能失效是由於某些操作修改了它所依賴的物件的"LAST_DDL"。通常來說這些操作包括物件維護操作,比如 ALTER, GRANT, REVOKE, replacing views 等等。還有就是收集 optimizer statistics 也會造成 cursor 失效,進而導致 library cache 的重灌載。這個現象在 Oracle Server Application Developer's Guide 的object dependency maintenance 部分有描述。

物件失效以後,Oracle 嘗試在第一次訪問這個物件時去重編譯它。有些情況下,如果其它 session 已經 pin 住這個物件,可能就會出現問題。 很顯然,在有大量活躍使用者與複雜依賴關係(例如,很多交叉依賴的 packages 或package bodies)的情況下更容易出現問題。有些時候對物件的編譯會持續數小時從而阻止其它 session 對其的訪問。



在 library cache dump, level 10 可以看到:
查詢 ALTER ... COMPILE 語句和 lock=X 或 pin=X 的 objects/handles.

  • 提示
    • 需要頻繁使用的 stored PL/SQL 所依賴的物件,對其 altering,       granting, evoking 操作需要特別小心。實際上,解決這種問題很大程度上依賴於應用程式和系統維護的時間。應用程式開發者需要考慮某些決定可能會對應用程式的可擴充套件性及效能產生負面影響。

 

    • Load lock 總是以排它模式獲得的。
            如果 session load lock 繁忙,session       將一直等待,直到鎖變成可用。
  • 已知問題 :

Document 1309738.1  High 'library cache lock' Wait Time Due to Invalid Login Attempts

Document 10018789.8  Spin in kgllock / DB hang with high library cache lock waits 
Document 7423411.8  Process may hang waiting for "library cache load lock" with no holder 
Document 7706138.8  Process may hang waiting for "library cache load lock" with no holder 
Document 9675816.8  Bug 9675816 - Self deadlock with 'library cache lock' waits

參考

NOTE:7423411.8  - Bug 7423411 - Process may hang waiting for "library cache load lock" with no holder
NOTE:10018789.8  - Bug 10018789 - Spin in kgllock / DB hang with high library cache lock waits on ADG
NOTE:1298015.1  - WAITEVENT: "cursor: pin S wait on X" Reference Note
NOTE:296377.1  - Troubleshooting: High Version Count Issues
NOTE:7706138.8  - Bug 7706138 - Process may hang waiting for "library cache load lock" with no holder
NOTE:94036.1  - Init.ora Parameter "CURSOR_SHARING" Reference Note
NOTE:34579.1  - WAITEVENT: "library cache pin" Reference Note
NOTE:122793.1  - How to Find which Session is Holding a Particular Library Cache Lock
NOTE:9675816.8  - Bug 9675816 - Self deadlock with 'library cache lock' waits / OERI:17059
NOTE:62143.1  - Troubleshooting: Tuning the Shared Pool and Tuning Library Cache Latch Contention


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31439444/viewspace-2678575/,如需轉載,請註明出處,否則將追究法律責任。

相關文章