一、LRU 鏈:改良版最近最少使用算法
基本結構
- Buffer Cache 所有塊串成雙向鏈表
- **熱端** (MRU) ←→ **冷端** (LRU)
- 新讀入塊 → 放入**冷端頭部附近** (非最尾),避免瞬間被淘汰
訪問提升機制
- 塊被訪問 → 訪問計數 +1
- 計數 ≥ 2 → **移至熱端**,計數歸零
- 熱端塊長期保留,冷端優先淘汰
犧牲者選擇流程
- 從冷端頭掃描
- 遇訪問計數 ≥ 2 → 移熱端,**不淘汰**
- 遇髒塊 → 移髒 LRU,**不淘汰**
- 首個「計數<2 且非髒」塊 → **犧牲者**,新塊覆蓋
二、髒塊與髒 LRU 鏈
髒塊定義
Buffer Cache 中塊內容 ≠ 磁碟塊內容 (用戶修改過、未刷盤)。
髒 LRU 鏈作用
- 專門串聯髒塊
- LRU 掃描發現髒塊時移入,**下次掃描直接跳過**
- 髒 LRU 達閾值 → 喚醒 DBWn 刷新
DBWn 刷新觸發條件
- 髒 LRU 長度達限制
- 檢查點隊列推進 (CKPT 進程)
- 表空間離線/備份模式結束
三、檢查點隊列:實例恢復的關鍵
- 塊變髒時 → 同時掛入**檢查點隊列尾部**
- 節點記錄:塊位置、對應 Redo 位置
- 隊列頭 = **最早變髒塊** = **檢查點位置**
- CKPT 進程每 3 秒將位置寫入**控制檔**
- 崩潰恢復:讀控制檔位置 → 從該 Redo 起始點重放 → **零資料遺失**
四、關鍵等待事件與調優
| 事件 | 原因 | 對策 |
| free buffer waits | LRU 掃描過多不可淘汰塊 (髒塊多、熱塊多) | 增加 DBWn、調大 _db_block_write_batch、大頁面記憶體 |
| log file switch completion | Redo Log 切換慢 | 增大 Redo Log、多組多路鏡像 |
| checkpoint not complete | 檢查點推進慢 | 優化 DBWn、調整 FAST_START_MTTR_TARGET |
五、LRU 掃描統計視圖
SELECT * FROM V$SYSSTAT WHERE NAME LIKE '%free buffer%';
-- free buffer inspected:累計掃描不可淘汰塊數
-- free buffer requested:請求空閒塊次數
總結
Oracle 透過**改良 LRU + 髒 LRU + 檢查點隊列**三大結構協作,實現:查詢路徑極短 (僅改標誌位)、髒塊平滑刷新、崩潰秒級恢復,是高併發高可用核心基石。