Shared Pool 透過 Free List 管理空閒記憶體塊,依大小分桶。8i 僅 11 個 Bucket(44~32780 位元組指數增長),導致小塊集中 Bucket 0,碎片極多(單 Bucket 超 2000 chunk 即判定碎片過多),搜尋耗時造成 Latch 爭用。9i 擴展為 255 個 Bucket:
細緻分桶大幅降低單 Bucket chunk 數,提升分配效率,解決 8i 過大 Shared Pool 反而降低效能的悖論。
X$KSMSP(Kernel Storage Memory Management SGA Heap)每列代表一個 Chunk。關鍵欄位:
KSMCHCOM:註釋(用途)KSMCHSIZ:塊大小KSMCHCLS:類別——FREE(可自由分配)、RECR(可重建,如共用 SQL)、FREEABL(Session/Call 結束可釋)、PERM(永久)啟動初期 ~2259 chunks,查詢 DBA_OBJECTS 後增至 2358,硬解析導致分配/分割產生碎片。可建立暫存表定期快照比對 CHUNK 與 SUM 變化,量化碎片演進。
Library Cache = Hash Table (Buckets) → 雙向鏈表 → Handle → Object (Dependency/Child/Authorization)。
* 顯示計數,熱點 Bucket 鏈表極長。事件 ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME LIBRARY_CACHE LEVEL 4/8/16/32' 可轉儲完整結構,Level 4 顯示 Handle/Object/Child/Dependency/Data Block(含 Heap Dump:Diana Tree、P-Code、Source Code、Shared Cursor Context)。
SELECT * FROM SCOTT.DEPT vs SELECT * FROM SCOTT.dept 產生不同 Hash,導致無法共享。| 等待事件 | 觸發情境 | 關鍵參數 | 診斷 SQL |
|---|---|---|---|
| Library Cache Pin | 編譯/重編譯 PLSQL/View/Type、ALTER/GRANT/REVOKE 導致物件失效需重編,但其他 Session 持有 Shared Pin | P1=Handle Addr, P2=Pin Addr, P3=Mode+Namespace | V$SESSION_WAIT → X$KGLOB (Handle→Object) → X$KGLPN (Pin 持有者) → V$SESSION_WAIT/V$SQLAREA 定位阻塞碼 |
| Library Cache Lock | 同一物件並發 DDL/編譯,排他鎖衝突 | P1=Handle Addr, P2=Lock Addr, P3=Mode+Namespace | 同 Pin 診斷路徑,鎖層級更高 |
模擬案例:Session 1 執行含 DBMS_LOCK.SLEEP 的 Procedure 持有 Shared Pin,Session 2 GRANT 同一 Procedure 等待 Exclusive Pin → Library Cache Pin 等待。查詢鏈路完整呈現。
簡訊群發系統周期性擁塞,V$SESSION_WAIT 大量 LATCH FREE,鎖定 SHARED POOL (latch#98) 與 LIBRARY CACHE (latch#99)。V$SQLAREA 發現單一 INSERT 陳述式(使用繫結變數)VERSION_COUNT = 7023。
Metalink Bug 1210242:啟用 TIMED_STATISTICS=TRUE 時,特定 SQL 游標不共享。執行進度監控(_SQLEXEC_PROGRESSION_COST 預設 1000)引入額外 Row Source,導致成本/計劃變化產生大量 Child Cursor,佈滿同一 Bucket 鏈表,掃描競爭劇烈。
ALTER SYSTEM SET TIMED_STATISTICS=FALSE(動態生效) → Child Cursor 迅速收斂至 1~2 支。_SQLEXEC_PROGRESSION_COST=0 關閉進度監控。驗證:關閉後 V$SQL 中 OPTIMIZER_COST > 1000 的 SQL 僅 5 筆,其中 4 筆 VERSION_COUNT > 10,問題徹底解決。
TIMED_STATISTICS 與進度監控,必要時關閉隱含參數。V$LATCH(SPIN_GETS)、V$SQLAREA.VERSION_COUNT、X$KSMSP 碎片趨勢。