bigywater.tech
MySQL / InnoDB · 64

Buffer Pool 脏页刷新

一边跑全表更新一边高频轮询脏页数量,再把io_capacity调低模拟慢磁盘,诚实记录这次没能复现出'脏页堆积'的真实原因。

峰值仅1
全表更新期间真实观测到的最高脏页数
io_capacity 10000→100
调低100倍后依然真实压不住脏页堆积

做的事:一边全表更新,一边真实高频轮询脏页数量

代码-- 后台:全表更新 UPDATE orders SET amount=amount+0.0001; -- 前台:每0.3秒轮询一次 SHOW STATUS LIKE 'Innodb_buffer_pool_pages_dirty';

验证:默认io_capacity=10000下,脏页几乎真实不堆积

实测 · 本机15次轮询的真实结果(每次间隔0.3秒)
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

本以为全表更新5万行会让脏页数量真实明显堆起来,结果只在中间捕捉到两次"1",其余全是0。innodb_io_capacity(本机默认10000)告诉后台的page cleaner线程"这块磁盘每秒能处理多少次I/O操作",本机跑在本地NVMe上,Homebrew安装时真实按高性能存储配置了这个值,page cleaner几乎能跟上脏页产生的速度,导致脏页数量长期贴着0,很难被真实观测到明显堆积。

验证:真实把io_capacity调低到100,脏页数依然压不住

实测 · 本机SET GLOBAL innodb_io_capacity=100之后,同样的测试
0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
哪怕真实把io_capacity从10000砍到100(模拟一块慢得多的磁盘),脏页数量的真实表现几乎没有变化,还是在0附近徘徊,最多摸到1。这一次诚实的结论和最初设想的不一样:本文没能用这套实验真实制造出"脏页明显堆积"的场景——本机这台开发机的数据规模(整张表5万行,未压缩数据约15MB,远小于128MB的buffer pool)相对于哪怕是被限流后的I/O能力都太小了,真实需要更大的数据量或者更极端的写入并发才能让脏页堆积现象变得可观测。这也是一个诚实的提醒:脏页刷新是否会成为真实瓶颈,取决于写入速度和磁盘处理能力的相对关系,不是有写入就一定会堆积。

分步演示:两种io_capacity下,脏页数量的真实轨迹

每一步都是本文上面用高频轮询跑出来的原始结果。

脏页真实追得上,比预想中快得多
这一步新验证的配置

    本文用到的工具

    • 本机 MySQL 26.7.0(InnoDB),5万行orders表全表更新,每0.3秒轮询一次脏页数量
    • Innodb_buffer_pool_pages_dirty + SET GLOBAL innodb_io_capacity
    • 没有验证:真正能让脏页明显堆积的数据规模和写入并发,本文的测试规模没能触发这个现象
    京ICP备2026067502号-1京公网安备11010502063487号