InnoDB Buffer Pool 採用改進 LRU(Midpoint Insertion Strategy),將列表劃分為 Young (熱) 區 5/8 和 Old (冷) 區 3/8,新讀頁插入 Old 區頭部(中點),防止全表掃描、一次性大查詢污染熱數據。本文還原源碼級邏輯。
一、 核心數據結構
- Buffer Pool 由多個 Block(默認 16KB 頁 + 控制塊)組成雙向鏈表。
- LRU 列表頭 = Young 區頭(最熱),尾 = Old 區尾(最冷)。
- 中點 = Old 區頭 = Young 區尾的下一個節點。
二、 中點插入算法流程
- 頁不在 Buffer Pool(缺頁中斷):
① 從磁盤讀取頁到新 Block。
② 若 LRU 已滿,淘汰尾部 Old 區 Block(LRU 受害者)。
③ 插入中點(Old 區頭),標記為 Old 區頁。
→ 一次性掃描頁停留在 Old 區,不進 Young 區。
- 頁已在 Buffer Pool(命中):
① 若在 Young 區:移動到 Young 區頭(MRU 端)。
② 若在 Old 區:升級為 Young → 移動到 Young 區頭。
→ 熱頁自動上浮,冷頁逐漸下沉。
三、 關鍵參數與比例
| 參數 | 默認值 | 含義 |
| innodb_old_blocks_pct | 37 | Old 區佔比 3/8 ≈ 37% |
| innodb_old_blocks_time | 1000 (ms) | Old 區頁首次訪問後,需等待此毫秒數再次被訪問才升級 Young,防預讀頁誤入熱區 |
四、 預讀頁保護機制
- 線性/隨機預讀將頁載入 Old 區。
- 若預讀頁從未被真實查詢訪問,停留 Old 區最終被淘汰。
- 若被訪問,需等待
innodb_old_blocks_time 後再次訪問才升級,濾除「掃描即訪問」噪聲。
五、 監控指標
SHOW ENGINE INNODB STATUS\G
-- BUFFER POOL AND MEMORY 區塊
-- Old database pages: 12345
-- Pages made young: 678, not young: 0
-- youngs/s: 12, non-youngs/s: 3
關注 youngs/s(熱頁產生率)與 non-youngs/s(冷頁停留率),調優 innodb_old_blocks_pct、innodb_old_blocks_time。
六、 總結
Midpoint Insertion + Old 區停留時間門檻,構成 InnoDB 抗掃描污染、保護熱點數據的雙重防線。理解機制,才能在極端負載下精準調優。
- 上一篇文章: MySQL REPLACE INTO 與 INSERT ... ON DUPLICATE KEY UPDATE 實戰:排序遷移單條 SQL 解決方案
- 下一篇文章: MySQL 磁盤滿故障行為分析:Select 正常、Insert 延遲卡死、Show Slave Status 死鎖、Show Status 連環卡死
Copyright ©
程式碼之家 All Rights Reserved