当前位置: 首页 > news >正文

深入 InnoDB 内核:Buffer Pool 中的 Flush List 到底解决了什么问题?

深入 InnoDB 内核:Buffer Pool 中的 Flush List 到底解决了什么问题?

长期和 MySQL 打交道,我发现一个现象:

很多开发知道“脏页要刷盘”,但并不知道 MySQL 是“怎么知道哪些页是脏的”。

而这个问题的答案,正是今天要讲的主角 ——Flush List(刷盘链表)

本文将从一次最普通的 UPDATE 操作出发,带你真正理解:

  • 什么是脏页
  • Flush List 是如何产生的
  • Flush List 在 InnoDB 中的真实作用
  • 它和数据库性能、稳定性有什么关系

一、先从一个 DBA 常问的问题说起

在排查 MySQL 性能问题时,经常会被问到:

  • 为什么 MySQL 会突然大量刷盘?
  • 为什么 Buffer Pool 很大,但 IO 还是很高?
  • MySQL 是怎么知道哪些页需要写回磁盘的?

如果你只停留在“有脏页”“后台线程会刷盘”这个层面,其实是不够的。

真正的关键在于:
👉InnoDB 是如何“管理”脏页的?


二、Buffer Pool 一定会产生内存碎片吗?

先回答一个容易被忽略的问题。

1️⃣ 结论先行:一定会有

Buffer Pool 的大小是我们在参数里配置的,比如:

innodb_buffer_pool_size = 16G

InnoDB 的缓存页是固定大小(16KB),还需要额外的描述数据结构(控制块)。

结果就是:

  • Buffer Pool 被划分成:

    • 缓存页
    • 描述数据块
  • 剩余的一点点空间,既放不下页,也放不下描述块

这部分内存就成了不可避免的内存碎片

2️⃣ InnoDB 如何尽量减少碎片?

作为内核级实现,InnoDB 做了一件非常“工程化”的事情:

让缓存页和描述数据块在内存中尽量连续排列

而不是东一块、西一块地分散分配。

这也是为什么 Buffer Pool 的内存布局非常“规整”,目的只有一个:

👉减少碎片,提高整体内存利用率


三、脏页是怎么产生的?

我们回到最核心的问题。

一次 UPDATE 的真实过程(简化版)

UPDATEuserSETage=30WHEREid=1;

InnoDB 内部发生的事情是:

  1. 如果数据页不在 Buffer Pool
    → 从磁盘加载到 Buffer Pool

  2. 内存中的缓存页修改数据

  3. 此时:

    • 内存页的数据 ✅ 已更新
    • 磁盘页的数据 ❌ 还是旧的

这就产生了一个状态:

内存页 ≠ 磁盘页

于是,这个缓存页就被称为:

👉脏页(Dirty Page)


四、并不是所有缓存页都需要刷盘

这里有一个非常关键的事实,很多人会忽略:

Buffer Pool 里的页,绝大多数时间只是“被读过”,并没有被改过。

比如:

  • SELECT 查询加载的数据页
  • 索引扫描读取的页

这些页:

  • 在 Buffer Pool 中
  • 但和磁盘数据完全一致
  • 根本不需要刷盘

那么问题来了:

❓ InnoDB 怎么区分
“哪些页被修改过,需要刷回磁盘”?

答案就是 ——Flush List


五、Flush List:专门管理“脏页”的链表

1️⃣ Flush List 是什么?

Flush List 本质上是:

一个由“被修改过的缓存页”组成的双向链表

它和 free list 很像,但职责完全不同:

链表作用
Free List管理空闲缓存页
LRU List管理缓存页的冷热
Flush List管理所有脏页

2️⃣ Flush List 是如何构建的?

关键点在这里:

只有当缓存页发生修改时,才会进入 Flush List

流程是:

  1. 缓存页被 UPDATE / DELETE / INSERT 修改
  2. InnoDB 标记该页为 dirty
  3. 该页对应的描述数据块
  4. 被挂到 Flush List 中

Flush List 使用的是:

  • 双向链表
  • 头尾指针都在 Buffer Pool 的控制结构中

3️⃣ 用“伪代码”理解更直观

假设:

  • Page01 被修改
  • Page02 随后也被修改

那么逻辑上类似:

flush_list_head -> page01 -> page02 -> flush_list_tail

每一个节点,本质都是:

“缓存页的描述数据块”

而不是缓存页本身。


六、Flush List 对 DBA 意味着什么?

站在 DBA 的角度,Flush List 的价值非常大。

✅ 1. 精准刷盘

InnoDB 后台刷盘线程(如 page cleaner):

  • 只遍历 Flush List
  • 不会扫描整个 Buffer Pool

这保证了:

刷盘是“有目标的”,而不是“全表扫描式的 IO”


✅ 2. 控制 IO 峰值

刷盘策略(如 checkpoint)本质上就是:

  • 控制 Flush List 的长度
  • 控制单位时间内刷多少脏页

这直接影响:

  • IO 抖动
  • TPS 稳定性
  • 高峰期是否出现卡顿

✅ 3. 故障恢复的基础前提

只有:

  • 脏页被记录在 Flush List
  • redo log 能配合使用

InnoDB 才能做到:

“崩溃后,知道哪些页需要恢复,哪些不需要”


七、一句话总结(DBA 视角)

如果让我用一句话总结 Flush List:

Flush List 是 InnoDB 管理脏页的核心数据结构,是性能可控刷盘的基础,也是数据库稳定运行的关键保障。

你在生产环境中看到的:

  • IO 抖动
  • checkpoint 卡顿
  • Buffer Pool 命中率异常

背后,几乎都绕不开Flush List 的长度和刷盘节奏


http://www.cnnetsun.cn/news/66590.html

相关文章:

  • 计算机硬件解剖:从拆解到性能优化
  • 基于STM32单片机盲人导航 导盲杖 智能拐杖系统 超声波测距 老人防丢 防摔到 跌倒检测报警 物联网控制系统 DIY 成品套件 DIY设计 实物+源程序+原理图+仿真+其它资料
  • AutoGPT联网搜索功能如何启用?详细配置说明来了
  • 企业内部智能客服新选择:基于LobeChat的定制化解决方案
  • AutoGPT镜像用户增长数据曝光:三个月突破10万下载
  • Python 1级编程考试模拟题库(5套精选)
  • 从零开始部署LobeChat:打造个人专属的大模型对话门户
  • Jenkins环境配置篇-更换插件源
  • 行为驱动开发(BDD)在软件测试中的实践流程
  • Trae的使用
  • easy_nbt(Bugku杂项入门)
  • Hyperworks MotionView软件下的发动机激励噪声仿真:识别车内噪声的技术路线揭秘
  • 三层电梯控制系统是PLC入门经典项目。今天拆解一套基于FX3U PLC和GS2107触摸屏的方案,重点聊聊那些容易掉坑的细节
  • 零基础入门:Flutter + 开源鸿蒙打造可视化儿童编程工具
  • 归并排序算法实现,kotlin,c++,python
  • 京东商品列表API,Python请求示例
  • Hadess基础到实践,如何详细管理Npm制品
  • Java 开发问题:类名与注解名冲突问题
  • 如何衡量推广效果(如投产比、转化率)?一位餐饮老板的实战自白
  • 程序员必看!万字长文详解大模型“深度研究“新范式,小白也能入门AI智能体开发!
  • 大模型安全威胁全解析,Agent架构设计避坑指南,小白必看
  • SMDJ45A单向 TVS瞬态抑制二极管 :3000W浪涌保护管 防雷击抗静电
  • Foundation 文本
  • Sui 主网升级至 V1.61.2
  • 25、Kubernetes 应用部署与管理实践
  • 31、容器化应用设计理念与实践
  • 如何评估LobeChat的加载速度与响应延迟?性能基准测试
  • 缓存与数据库一致性解决方案深度解析
  • 消息队列真仙:我的道念支持最终一致性
  • Spring Boot项目推送Gitee全流程(进阶)