MySQL的LRU采用冷热分离策略,将Buffer Pool划分为热区(63%)和冷区(37%),新页入冷区头部,仅1秒后再次访问才晋升热区,并在热区内按3/4规则优化移动。

MySQL 的 LRU 算法不是简单维护一个链表,而是通过冷热分离策略大幅优化缓存行为,核心目标是防止全表扫描、预读等操作污染热点数据。
冷热区域按比例划分
LRU 链表被逻辑拆分为两个区域:
- 热数据区:占 Buffer Pool 的约 63%,存放真正高频访问的页
- 冷数据区:占约 37%,由 innodb_old_blocks_pct 参数控制,默认值为 37
- 冷热交界处称为 midpoint,是链表中一个关键分界位置
新页默认进入冷区头部
任何数据页首次从磁盘加载进 Buffer Pool 时,不会直接进入热区,而是插入到冷数据区的链表头部,并打上时间戳。这种设计能有效隔离以下干扰:
- 预读加载的大批相邻页(如一次预读 16 个页)
- 全表扫描过程中顺带读入的大量临时页
- 低频查询偶然触发的单次访问页
晋升热区需满足“1 秒规则”
冷区页不会自动升级,必须经过验证期才可能进入热区:
- 由参数 innodb_old_blocks_time 控制,单位毫秒,默认 1000(即 1 秒)
- 若某页在加载后 1 秒内被访问,仅在冷区内部移动到头部,不晋升
- 只有在加载 1 秒之后再次被访问,该页才会被移到热数据区的链表头部
- 这个延迟机制本质是过滤“瞬时热度”,确认真实访问持续性
热区内部也做了访问优化
为避免高频页反复移动带来链表开销,InnoDB 在热区内引入“3/4 黄金分割”规则:
- 热数据区被进一步划分为前 1/4(稳定区)和后 3/4(活跃区)
- 只有位于后 3/4 区域的页被访问时,才将其移至热区头部
- 已在前 1/4 的页即使被访问,也不移动——减少无谓链表操作,提升 CPU 效率










