同一条 SQL 第一次慢、第二次快,不能只用“缓存了”三个字解释。InnoDB 缓存的是页,访问路径上的数据页、索引页是否已经在 Buffer Pool 里,直接影响一次查询要不要碰磁盘。

Buffer Pool 的核心不只是加速读取,还包括热点保护、淘汰策略、脏页管理和预读控制。理解它,才能解释缓存命中、偶发抖动、大扫描污染和刷盘压力之间的关系。

先把机制边界说清楚

Buffer Pool 是 InnoDB 最核心的内存结构,用来缓存数据页、索引页、自适应哈希索引等内容。InnoDB 读写数据的基本单位是页,SQL 快不快,很大程度取决于访问路径上的页是否已经在 Buffer Pool 里。

整体路径

Buffer Pool:数据页为什么能命中内存

上面这张图先看粗线条:宏观上,Buffer Pool 位于 SQL 执行和磁盘文件之间。查询先按索引路径定位需要的页,如果页在内存里就直接读;不在内存里才触发磁盘读。更新也先修改内存页,页变脏后再由后台线程刷回磁盘。

底层流程

Buffer Pool:数据页为什么能命中内存:执行路径

底层拆解先看数据结构。「Buffer Pool」至少涉及下面几类结构:

  • Buffer Pool Page:缓存的数据页或索引页。
  • LRU 链表:管理冷热页,决定淘汰顺序。
  • Flush List:管理脏页,配合 checkpoint 刷盘。
  • Free List:保存空闲页,供新读入页面使用。

再看完整执行流程:

  1. 执行器通过存储引擎访问索引或数据页。
  2. Buffer Pool 查找目标页是否命中。
  3. 命中则直接读取或修改内存页。
  4. 未命中则从磁盘读入,并放入 LRU 的合适位置。
  5. 脏页后续进入刷盘链路。

取舍与边界

版本差异上,MySQL 5.7 和 8.0 的 Buffer Pool 基本模型一致。8.0 在实例管理、预热、监控指标和自适应配置上更完善,但核心仍是页缓存、LRU、脏页刷盘和 checkpoint 协作。

Buffer Pool 的短板是容易被错误访问模式污染。大范围扫描、缺索引查询、报表 SQL 可能把热点页挤出去;Buffer Pool 再大,也挡不住无效扫描不断搬运冷数据。

典型问题:用机制化例子排查

缓存抖动可以用页的生命周期来看:一条查询把哪些页读进 Buffer Pool,这些页能停留多久,会不会被大扫描挤出去,脏页又什么时候要刷回磁盘。

可以落到这些动作:

  • 先看 Buffer Pool 命中率、脏页比例和读写 IO,而不是直接加内存。
  • 用索引和查询范围保护热点页,避免大扫描污染缓存。
  • 核心库区分 OLTP 请求和报表请求,必要时读写或冷热隔离。
  • 重启后可用 Buffer Pool dump/load 预热关键页面。

收束:缓存命中背后是页治理

Buffer Pool 不是泛泛的缓存层,而是 InnoDB 页的工作区。热点保护、淘汰、预读和脏页刷盘共同决定了 SQL 是碰内存还是碰磁盘。


关于十三Tech

我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。

我相信 AI 是程序员的最佳搭档,也希望帮助每一位开发者更好地驾驭 AI。

如果你想继续跟完这套「图解 MySQL」,欢迎关注公众号 「十三Tech」。后续会继续按机制、图解和实战排查这条线更新。

十三Tech公众号二维码