事务提交不要求数据页立刻落盘,这是 redo log 带来的能力;但被修改过、还没刷回磁盘的页不会凭空消失,它们会以脏页的形式留在 Buffer Pool 里。
脏页机制把写入主路径变快了,也把刷盘成本延后了。问题在于,延后的债务迟早要还:checkpoint 推进、后台刷盘、磁盘能力和写入突增都会影响系统抖动。
先把机制边界说清楚
脏页指 Buffer Pool 中已经被修改、但还没刷回磁盘的数据页。事务提交时依赖 redo log 保证崩溃恢复,不要求数据页立刻落盘,所以更新可以先改内存,再由后台线程慢慢刷脏。
整体路径
上面这张图先看粗线条:宏观上,写入路径分成两条线:前台事务写 redo 并修改 Buffer Pool,后台线程推进 checkpoint 并把脏页刷回磁盘。只要后台刷盘能跟上,前台就稳定;一旦 redo 空间逼近、脏页比例过高或需要淘汰脏页,前台请求就会被拖住。
底层流程
底层拆解先看数据结构。「脏页与刷盘」至少涉及下面几类结构:
- 脏页:内存内容比磁盘新的页。
- Flush List:按最早修改 LSN 管理脏页。
- Checkpoint:标记 redo 已覆盖到哪个持久化点。
- redo log:崩溃恢复时重放脏页修改。
再看完整执行流程:
- 事务更新记录,修改 Buffer Pool 页。
- 写 redo log,保证崩溃可恢复。
- 页进入脏页链表。
- 后台线程按策略刷脏推进 checkpoint。
- 刷盘压力过大时前台写入被动等待。
取舍与边界
版本差异上,MySQL 5.7 以后 InnoDB 刷盘策略已经较成熟,8.0 在 redo log 配置、并发刷盘和监控可观测性上继续增强。不同版本参数名和默认值会变化,但脏页与 checkpoint 的关系不变。
脏页机制的短板是成本延迟。提交时看似很快,但刷盘债务会积累;大事务、突发写入、低 io_capacity 或慢盘都会让债务在某一刻集中爆发。
典型问题:用机制化例子排查
批量更新不只制造 redo,也会制造大量脏页。提交完成不代表成本结束,如果后台刷盘跟不上,后续请求会替前面的写入压力还账。
可以落到这些动作:
- 控制单事务修改规模,避免一次制造过多脏页。
- 根据磁盘能力设置 innodb_io_capacity 和相关刷盘参数。
- 监控脏页比例、checkpoint age、redo 使用率和 fsync 延迟。
- 写入高峰前避免大 DDL、大批量更新和报表扫描叠加。
收束:写入稳定性看后台还账
脏页与刷盘告诉我们:写入性能不是只看提交那一刻,而要看后台能否平滑还账。稳定性来自持续刷,而不是最后硬刷。
关于十三Tech
我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。
我相信 AI 是程序员的最佳搭档,也希望帮助每一位开发者更好地驾驭 AI。
如果你想继续跟完这套「图解 MySQL」,欢迎关注公众号 「十三Tech」。后续会继续按机制、图解和实战排查这条线更新。

