news 2026/5/1 5:42:24

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入 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 的长度和刷盘节奏


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 8:51:27

模电复习-BJT章

因为该章节有很多部分和MOS管分析方法相类似,所以我偷个懒了。大家有需要的可以去看看MOS管的部分。 模电复习-场效应管(一)-CSDN博客 模电复习-场效应管(二)-CSDN博客

作者头像 李华
网站建设 2026/4/23 17:26:06

不想被封号?试试用LobeChat自建安全可控的AI对话平台

不想被封号?试试用LobeChat自建安全可控的AI对话平台 在智能助手日益渗透工作与生活的今天,你有没有经历过这样的瞬间:正在撰写一份关键报告,AI突然中断响应;或是输入一段内部项目描述后,系统提示“内容受限…

作者头像 李华
网站建设 2026/5/1 2:58:29

nginx路由重定向

# n8n 路径重定向:将 /n8n 重定向到 /n8n/location /n8n {return 301 /n8n/;}# n8n 前端项目 (history 模式)location /n8n/ {alias /temp/n8n/; # 注意:使用 alias 而不是 root,并且路径末尾要加 /index index.html index.htm;try_file…

作者头像 李华
网站建设 2026/5/1 9:48:36

丽江工业无缝管,耐腐蚀抗高压,寿命提升3倍!

在新乡地区,不锈钢光亮退火管市场近年来呈现出价格信息逐步透明化的趋势。据行业监测数据显示,目前区域内约有68%的经营主体已实现明码标价,其中42%的企业在官网或销售平台公示了详细的产品规格与对应价格区间,整体价格公示完善度…

作者头像 李华