Oracle Latch:保護 SGA 共享記憶體結構的輕量級序列化鎖
Latch 是 Oracle 保護 SGA 區共享資料結構 (如 Buffer Cache 鏈表、Library Cache 雜湊桶) 的低層序列化機制。與 Enqueue (行鎖/表鎖) 不同,Latch 無等待佇列、採用 Spin-Sleep 重試、由 PMON 清理異常持有。本文深入解析 Latch 類型、V$LATCH 統計視圖、Willing-to-Wait vs Immediate 模式、沖突診斷指標。
Latch vs Enqueue (隊列鎖) 核心差異
| 特性 | Latch (閂鎖) | Enqueue (隊列鎖) |
| 保護對象 | SGA 記憶體結構 (Buffer Header, Library Cache Bucket) | 使用者資料 (Table, Row, Transaction) |
| 持有時間 | 極短 (微秒級) | 較長 (交易持續期間) |
| 等待機制 | Spin (CPU 忙等) → Sleep (指數遞增) | OS Queue (FIFO),進程休眠喚醒 |
| 死鎖處理 | 層級機制防止,PMON 清理死持有 | 死鎖偵測 (DIAG) + 受害者回滾 |
| 可見性 | V$LATCH, V$LATCHHOLDER, V$LATCHNAME | V$LOCK, V$SESSION_WAIT |
| 模式 | Willing-to-Wait / Immediate | 共享 (S) / 排他 (X) / 多種子模式 |
Latch 兩種請求模式
- Willing-to-Wait (大多數):無法立即取得 → Spin → Sleep → 重試,直到成功
GETS:成功請求次數
MISSES:首次嘗試失敗次數 (需 Spin/Sleep)
SLEEPS:實際進入 Sleep 次數
SPIN_GETS:Spin 成功次數 (10g+)
WAIT_TIME:總等待微秒數
- Immediate (少數):無法立即取得 → 立即返回失敗,不等待
IMMEDIATE_GETS:成功次數
IMMEDIATE_MISSES:失敗次數
關鍵統計視圖:V$LATCH
-- 查看高沖突 Latch
SELECT NAME, GETS, MISSES, SLEEPS, IMMEDIATE_GETS, IMMEDIATE_MISSES,
ROUND(MISSES/DECODE(GETS,0,1,GETS)*100,2) MISS_PCT,
ROUND(SLEEPS/DECODE(MISSES,0,1,MISSES)*100,2) SLEEP_PCT
FROM V$LATCH
WHERE GETS > 0
ORDER BY MISS_PCT DESC;
-- 查看特定 Latch 詳細
SELECT * FROM V$LATCH WHERE NAME = 'cache buffers chains';
常見高沖突 Latch 類型與對策
| Latch Name | 保護對象 | 典型沖突原因 | 緩解方向 |
| cache buffers chains | Buffer Cache 雜湊鏈 | 熱塊 (Hot Block)、全表掃描、索引根塊競爭 | 增加 _DB_BLOCK_HASH_BUCKETS、分區表、避免熱點索引 |
| library cache | SQL/PLAN 快取 | 硬解析過多、未使用綁定變數、共用池太小 | CURSOR_SHARING=FORCE/SIMILAR、增大 SHARED_POOL、綁定變數 |
| shared pool | 共用池記憶體分配 | 大物件分配、碎片化 | KEEP/RECYCLE Pool、大物件預分配 |
| redo allocation / redo copy | Redo Log Buffer | 高提交頻率、大批次 DML | 批次提交、增大 LOG_BUFFER、NOLOGGING 操作 |
| row cache objects | Data Dictionary Cache | 頻繁 DDL、權限檢查 | 增大 SHARED_POOL、固定物件統計 |
Latch 層級機制 (防死鎖)
- 每個 Latch 有層級 (0-15),持有高層級 Latch 時不可再取得同/低層級
- 防止循環等待:A(Level 5) → B(Level 3) 合法;B(Level 3) → A(Level 5) 非法
- 查看層級:
SELECT NAME, LEVEL# FROM V$LATCHNAME ORDER BY LEVEL#;
診斷工具與腳本
-- 1. Server Manager / Enterprise Manager: Latch 監控頁面
-- 2. Tanel Poder 的 latchprofx.sql (需 SYS) - 進階取樣分析
-- 3. AWR 報告: "Latch Activity" 章節
-- 4. ASH 查詢:
SELECT EVENT, COUNT(*) FROM V$ACTIVE_SESSION_HISTORY
WHERE EVENT LIKE 'latch%' GROUP BY EVENT ORDER BY 2 DESC;
最佳實踐總結
- 優先解決 Library Cache / Shared Pool Latch:綁定變數、適當共用池大小
- Cache Buffers Chains:識別熱塊 (
X$BH 配合 V$SESSION_WAIT),考慮 Hash Partition、Reverse Key Index
- 避免在應用層模擬 Spin:信任 Oracle 內建機制
- 定期收集 AWR/ASH,建立 Latch 基線,異常時快速比對