DB Buffer Cache 是資料存取核心。服務器進程讀取/修改塊的完整生命週期:鎖定 Latch → 讀入/建立 Undo → 生成 Redo → 修改塊 → 掛髒塊鏈表 → LRU 管理 → DBWN 依 Checkpoint 隊列寫入。
一、塊不在 Cache (Cache Miss) 路徑
- 請求表頭行鎖 (Row Lock) → 成功。
- 從資料檔讀塊 → 放入 Buffer Cache 空閒區或覆蓋 LRU 尾端非髒塊。
- 若非髒塊不足 → 觸發 DBWN 寫髒塊騰空間。
- **鎖定 Buffer Cache Latch** → 寫入塊頭 ITL/SCN、將舊值寫入 Undo (供 Rollback/Read Consistency)。
- **鎖定 Redo Log Buffer Latch** → 生成 Redo Entry (ROWID、舊/新值、SCN、Undo 修改資訊) 寫入 Log Buffer。
- Log Buffer 達 1/3 或 1MB 或 3 秒或 Checkpoint 或 Commit 或 DBWN 前 → **LGWR 寫入 Redo Log File** → 釋放 Redo Latch。
- 修改塊內容 → 掛入 **Dirty Buffer LRU List** (髒塊鏈表)。
- 讀下一塊 → 重複上述動作 (單次可讀多塊,由
DB_FILE_MULTIBLOCK_READ_COUNT 控制)。
二、塊在 Cache (Cache Hit) 路徑
- SELECT:檢查塊頭 ITL/SCN → 有交易或 SCN > Query SCN → Undo 重構一致性塊;否則直接讀取。
- UPDATE:即使塊乾淨 (無 ITL、SCN < Query SCN) → **仍需鎖定表頭行鎖** → 成功才可修改;失敗等待。
三、關鍵背景進程協作
| 進程 | 觸發條件 | 核心動作 |
| LGWR | Commit、Log Buffer 1/3/1MB/3秒、Checkpoint、DBWN 前 | 同步寫 Redo Log File,保證持久化 |
| DBWN | 髒塊鏈表達臨界、Checkpoint、Buffer Cache 壓力 | 依 Checkpoint Queue Low RBA 升序寫髒塊,更新塊頭 SCN |
| CKPT | 每 3 秒、Log Switch、參數滿足 | 更新控制檔 Checkpoint RBA/SCN,指導恢復起點 |
| ARCH | Log Switch (Archive 模式) | 複製 Redo Log 至 Archive 目的地 |
四、Commit 批次寫入與 SCN
- 密集交易下,LGWR 批次寫入多筆 Commit 產生的 Redo (Group Commit)。
- 每筆 Commit 間隔 ~0.1 秒,產生不同 Commit SCN。
- LGWR 正常休眠,被喚醒後寫入喚醒時刻前所有累積 Redo,完成前不再受理新觸發。
五、Undo 也是 Buffer Cache 一部分
- Undo Segment 在 Buffer Cache 中開闢區域 (Undo Buffer)。
- 寫入順序:**先寫 Undo Buffer → 再生成 Redo (記錄 Undo 變化) → 再修改資料塊 → 最後寫資料檔**。
- 恢復時:**先重做 Undo → 再重做資料塊**,順序不可逆,否則 Rollback 無法重構前映像。
六、實務優化切入點
- 減少 Hard Parse → 降低 Library Cache Latch 爭用 → 間接減輕 Buffer Cache 壓力。
- 調大
DB_CACHE_SIZE / DB_KEEP_CACHE_SIZE → 提高命中率、減少物理讀。
- 啟用
DB_FILE_MULTIBLOCK_READ_COUNT 最佳化全掃讀取。
- 監控
V$WAITSTAT free buffer waits、buffer busy waits → 定位髒塊寫入/讀取瓶頸。
- 上一篇文章: Oracle COMMIT 內部機制全解析:LGWR/DBWN 協作、檢查點類型、實例恢復前滾回滾邏輯
- 下一篇文章: 深入解析 Oracle Shared Pool 架構與 SQL 解析機制
Copyright ©
程式碼之家 All Rights Reserved