在 Oracle 共享池(Shared Pool)中,Library Cache 是 SQL、PL/SQL、對象元數據等最核心的組件之一。當系統出現明顯的 library cache lock 等待 時,通常意味著:
共享池中的對象訪問、解析、失效或并發控制已經成為系統瓶頸。
本文從 內部原理 → 常見成因 → 定位方法 → 對應解決方案 → 風險評估 的角度,對 library cache lock 等待進行一次完整拆解。
一、Shared Pool 與 Library Cache Lock 的作用機制
共享池主要包含以下內容:
- Library Cache
- Data Dictionary Cache
- SQL Query Result Cache
- PL/SQL Function Result Cache
- Buffers for parallel execution messages
- Control structures
1. Library Cache Lock 的本質
library cache lock 用于控制多個客戶端(Session)對同一對象的并發訪問,它是:
- 在 對象句柄(object handle) 上獲取的鎖
- 用于保證:
- 某一時刻只有合法的訪問者可以操作對象
- 對象在被依賴期間不被修改
其獲取過程包括:
- 獲取 library cache 子鎖,掃描對象句柄列表
- 找到目標對象后,在句柄上放置 library cache lock
2. 它意味著什么?
- 一個 Session 正在:
- 解析 SQL
- 編譯對象
- 執行依賴對象的 PL/SQL
- 另一個 Session 想:
- 使用同一對象
- 修改 / 失效該對象
此時就會產生 library cache lock 等待。
二、如何在報告中識別
library cache lock
1. TKProf
- Overall wait event summary
- non-recursive / recursive statements
- library cache lock 等待時間顯著
2. AWR / Statspack
- Top Wait Events 中出現:
- library cache lock
- Library Cache Statistics 異常
三、常見成因一:SQL 因文字值無法共享(硬解析)
問題描述
SQL 本可使用綁定變量,卻使用了字面量(literal),導致:
- SQL 無法共享
- 每次執行都觸發 硬解析
- 頻繁獲取 library cache lock
定位方法
TKProf:
- 按 parse time 排序
- 檢查:
- Misses in library cache ≈ Parse count
- 查找 SQL 中是否存在大量文字值
解決方案
重寫 SQL,使用綁定變量
優點:
- 顯著提升 SQL 共享率
- 降低硬解析與 library cache 爭用
代價與風險:
- 費勁程度:中 / 高
- 風險:中
- 可能影響執行計劃
- 必須充分測試
驗證方式
- 實施后重新分析:
- AWR
- TKProf
- 若無改善:
- 重新確認是否為主要原因
四、常見成因二:共享池過小,已共享 SQL 被刷出
問題描述
- Shared Pool 太小
- 可共享 SQL 被頻繁老化
- 再次執行 → 硬解析 → library cache lock
定位方法
AWR / Statspack:
- Library Cache Statistics:
- Reloads 很高(每小時幾千)
- Invalidations 很少
- % SQL with executions > 1 > 60%
解決方案一:增大 Shared Pool
- 費勁程度:低
- 風險:低
- 除非物理內存不足
解決方案二(10g+):啟用 ASMM
- 設置:
- SGA_TARGET
- SGA_MAX_SIZE
- 自動調節共享池大小
解決方案三:Pin 關鍵對象
- 使用:
DBMS_SHARED_POOL.KEEP()
- 保留:
- 大型
- 高頻使用
- PL/SQL / Cursor
風險:
- 中度風險
- 過度 pin 可能引發 ORA-4031
五、常見成因三:Library Cache 對象失效(DDL / 統計信息)
1. DDL 導致失效
- CREATE / ALTER / DROP
- 級聯失效依賴游標
- 引發大量硬解析
解決方案:
- 避免在繁忙期執行 DDL
- 安排到維護窗口
2. 收集優化器統計信息
- ANALYZE
- DBMS_STATS
影響:
- 對象失效
- 大量硬解析
解決方案:
- 避開高峰期
- 使用 no_invalidate(10g+)
3. TRUNCATE 操作
- 本質是 DDL
- 同樣會引發對象失效
解決方案:
- 延后到低負載時段
六、常見成因四:跨 Session 編譯對象
問題描述
- 一個 Session 編譯對象(PL/SQL)
- 另一個 Session 正在執行 / 解析該對象
- 出現 library cache pin / lock 等待
定位方法
TKProf:
- library cache pin waits
- 伴隨對象編譯行為
解決方案
- 避免并發編譯
- 避免高峰期編譯
- 使用 HangAnalyze 定位阻塞鏈
七、常見成因五:開啟審計(尤其 RAC)
問題描述
- 審計會增加 library cache lock 獲取頻率
- RAC 中影響更明顯(全局資源)
定位方法
- AWR / Statspack:
- library cache lock waits
- 參數:
- audit_trail != none
解決方案
- 評估審計必要性
- 非強制合規場景可關閉
風險:
- 低風險
- 但需考慮合規要求
八、常見成因六:RAC 環境中的非共享 SQL
典型特征
- 單實例:表現為 latch 爭用
- RAC:表現為 library cache lock
定位方法
- TKProf:
- 大量硬解析
- AWR:
- % SQL with executions > 1 < 60%
- Soft Parse Ratio < 80%
解決方案一:綁定變量
(同原因一)
解決方案二:CURSOR_SHARING 參數
- EXACT(默認)
- FORCE
- SIMILAR
建議:
- 優先 Session 級設置
- 避免 Instance 級 FORCE
風險:
- 中度風險
- 可能導致執行計劃劣化
九、常見成因七:大量使用行級觸發器
問題描述
- 行級觸發器頻繁觸發
- 每次觸發:
- 檢查 mutating table
- 獲取 library cache lock
關鍵點:
觸發頻率比觸發器數量更重要
定位方法
- TKProf:
- 硬解析多
- recursive SQL
- trigger 相關痕跡
解決方案
- 評估是否必須使用行級觸發器
- 設計替代方案
風險:
- 中度風險
- 需充分測試
十、常見成因八:過多的子游標(Version Count)
問題描述
- 單條 SQL 生成大量子游標
- 多 Session 并發創建 → 爭用加劇
定位方法
- AWR:
- SQL ordered by Version Count
- V$SQLAREA.version_count > 500
- V$SQL_SHARED_CURSOR
常見誘因
- CURSOR_SHARING = SIMILAR
- 范圍謂詞(>、<)導致計劃差異
解決方案選擇
- 重寫 SQL 使用綁定(最佳)
- 或改用 CURSOR_SHARING = FORCE(有風險)
十一、總結:排查
library cache lock
的正確姿勢
一句話原則:
先判斷是不是“非共享 SQL”,再判斷是不是“對象失效或并發編譯”,最后才考慮參數和內存。
實戰順序建議:
- TKProf 看解析
- AWR 看共享率 / Reload
- 排查 DDL / Stats / Compile
- 再談參數調整
參考文檔
-
‘library cache lock’ Waits: Causes and Solutions
Doc ID 1952395.1
「喜歡這篇文章,您的關注和贊賞是給作者最好的鼓勵」
關注作者
【版權聲明】本文為墨天輪用戶原創內容,轉載時必須標注文章的來源(墨天輪),文章鏈接,文章作者等基本信息,否則作者和墨天輪有權追究責任。如果您發現墨天輪中有涉嫌抄襲或者侵權的內容,歡迎發送郵件至:contact@modb.pro進行舉報,并提供相關證據,一經查實,墨天輪將立刻刪除相關內容。




