MySQL Buffer Pool深度解析:当缓存页不足时如何基于LRU算法进行淘汰

1. 问题引入:free链表空了怎么办?

在之前的文章中,我们详细讲解了MySQL Buffer Pool中缓存页的划分、free链表的管理,以及数据页从磁盘加载到缓存页的过程。今天我们来分析一个更实际的问题:当Buffer Pool中的空闲缓存页用完时,系统该如何处理?

1.1 缓存页耗尽的必然性

随着数据库持续运行,不断有数据页从磁盘加载到Buffer Pool中:

  • 每次数据加载都会从free链表获取一个空闲缓存页
  • free链表中的节点会越来越少
  • 最终必然出现free链表为空的情况
markdown 复制代码
磁盘数据页 → 查找free链表 → 获取空闲缓存页 → 加载数据

当free链表耗尽时,新的数据页将无法加载,此时必须淘汰部分现有缓存页

2. 淘汰策略:该把谁"请"出内存?

2.1 什么是淘汰缓存页?

淘汰缓存页是指:

  1. 将被修改过的缓存页数据刷新到磁盘(如果它是脏页)
  2. 清空该缓存页
  3. 将其重新加入free链表,变为可用状态

这个过程确保了内存资源的循环利用,但引出一个关键问题:应该淘汰哪些缓存页?

3. 核心指标:缓存命中率

为了做出最优淘汰决策,MySQL引入了缓存命中率的概念:

场景 访问频率 命中率评估 淘汰优先级
缓存页A 100次请求中30次访问 高命中率 保留
缓存页B 加载后仅访问1次,后续100次请求无访问 低命中率 优先淘汰

核心原则:优先淘汰"占着茅坑不拉屎"的缓存页------即那些长期不被访问却占用内存资源的页面。

4. LRU链表:智能淘汰的指挥官

4.1 LRU基本概念

MySQL通过LRU链表(Least Recently Used,最近最少使用)来实现智能淘汰:

工作原理:最近被访问的缓存页移动到链表头部,久未访问的页面自然沉降到尾部。

4.2 LRU链表运作机制

数据加载时

当从磁盘加载数据页到缓存页:

  • 将该缓存页的描述信息块放入LRU链表头部
  • 表示这是最新被使用的页面
markdown 复制代码
[新加载的缓存页] → LRU Head → ... → LRU Tail
数据访问时

当查询或修改某个已存在的缓存页:

  • 无论该缓存页在LRU链表的哪个位置
  • 立即将其移动到链表头部
  • 表示它刚被访问过,近期可能再次被访问
markdown 复制代码
LRU Tail中的缓存页被访问 → 移动到LRU Head
淘汰决策时

当需要腾出空闲缓存页:

  • 直接从LRU链表尾部选取
  • 尾部的页面就是"最近最少使用"的页面
  • 将其刷新到磁盘后清空

5. 技术图解

图1:free链表耗尽的场景

复制代码
Buffer Pool (128MB)
┌─────────────────────────────────────┐
│ [数据] [数据] [数据] ... [数据]          │
│ 缓存页  缓存页  缓存页      缓存页      │
└─────────────────────────────────────┘
        ▲
        │ 无法加载新数据页
        │
磁盘文件 ────────────→ X (无空闲缓存页)

图2:LRU链表驱动的淘汰流程

复制代码
1. 识别LRU链表尾部页面(最少使用)
   ↓
2. 如果是脏页,刷新到磁盘
   ↓
3. 清空缓存页,加入free链表
   ↓
4. 加载新数据页到腾出的空间
   ↓
5. 新页面插入LRU链表头部

6. 思考题解答:表/行 vs 表空间/数据页

问题:SQL中的表、行与表空间、数据页之间是什么关系?

答案

  • 逻辑概念:表、列、行------面向开发者的抽象,关注数据结构
  • 物理概念:表空间、数据页------面向存储的实现,关注数据在磁盘的组织方式

类比

就像你看一本书,只关注"章节"和"段落"(逻辑),而不必关心"纸张"和"印刷墨迹"(物理)。数据库自动将逻辑结构映射为物理存储。

7. 总结要点

  1. free链表耗尽是常态:持续的数据加载必然导致空闲页用完
  2. LRU是淘汰依据:通过访问时间戳智能判断页面热度
  3. 头部-尾部机制:热点数据在头部,冷数据自然沉降尾部
  4. 性能保障:确保内存中保留的都是高价值数据,最大化缓存命中率

系列预告:下一篇文章将深入探讨MySQL LRU算法的优化细节,包括如何解决"全表扫描污染缓存"等经典问题。

参考资料:《MySQL专栏》

版权说明:本文内容整理自狸猫技术窝MySQL专栏,仅供学习交流使用。

相关推荐
霖霖总总11 小时前
[小技巧66]当自增主键耗尽:MySQL 主键溢出问题深度解析与雪花算法替代方案
mysql·算法
海奥华213 小时前
mysql索引
数据库·mysql
javachen__14 小时前
mysql新老项目版本选择
数据库·mysql
Dxy123931021614 小时前
MySQL如何高效查询表数据量:从基础到进阶的优化指南
数据库·mysql
Dying.Light14 小时前
MySQL相关问题
数据库·mysql
Re.不晚15 小时前
MySQL进阶之战——索引、事务与锁、高可用架构的三重奏
数据库·mysql·架构
chian-ocean17 小时前
CANN 生态进阶:利用 `profiling-tools` 优化模型性能
数据库·mysql
那个村的李富贵19 小时前
解锁CANN仓库核心能力:50行代码搭建国产化AIGC图片风格迁移神器
mysql·信息可视化·aigc·cann
斯普信专业组1 天前
构建基于MCP的MySQL智能运维平台:从开源服务端到交互式AI助手
运维·mysql·开源·mcp
Exquisite.1 天前
Mysql
数据库·mysql