最准信号是日志中“InnoDB: page_cleaner: XXXms intended loop took YYYYms”告警;核心看took是否超2000ms、flushed是否长期偏低、free buffers是否为0,并检查innodb_page_cleaners与buffer_pool_instances是否匹配及I/O和内存资源是否不足。

直接看日志里有没有 InnoDB: page_cleaner: 开头的延迟告警,这是最准的信号。
识别 page_cleaner 延迟的关键日志模式
Page Cleaner 线程一旦卡住,MySQL 错误日志(通常是 error.log)会持续输出形如以下的记录:
InnoDB: page_cleaner: 1000ms intended loop took 17248ms. The settings might not be optimal. (flushed=11 and evicted=0, during the time.)
注意三个核心字段:
-
1000ms intended loop:预期耗时(固定为 1 秒) -
took XXXXms:实际耗时 —— 超过 2000ms 就算明显异常,超过 5000ms 表示严重阻塞 -
flushed=N and evicted=M:本轮只刷了 N 页、淘汰了 M 页 —— 若flushed长期接近 0 或极低(比如
这类日志不是偶发警告,而是高频重复出现(每秒或每几秒一条),代表 Page Cleaner 已持续失能。它不报错,但比 ERROR 更危险 —— 是系统正在缓慢窒息的呼吸声。
结合 SHOW ENGINE INNODB STATUS 判断脏页压力
光看日志不够,必须立刻查实时内存状态。执行:
SHOW ENGINE INNODB STATUS\G
在输出中定位 BUF BUFFER POOL AND MEMORY 小节,重点关注:
-
Modified db pages:当前未刷盘的脏页总数 —— 超过 1000 就需警惕,>5000 通常已触发紧急刷脏 -
Free buffers:空闲 buffer 数量 —— 如果为0,说明 Buffer Pool 没有一页可用来加载新数据,写操作会直接受阻 -
Database pages和Buffer pool hit rate:若命中率跌破 95%,且Pages read ahead高,说明 I/O 已成瓶颈,Page Cleaner 在等磁盘
特别注意:Modified db pages 和日志中 flushed= 的数值长期不匹配(比如脏页 3000+,但每轮只刷个位数),基本锁定是刷脏能力被严重抑制。
检查 innodb_page_cleaners 与 innodb_buffer_pool_instances 是否失配
MySQL 8.0 默认启用多 Page Cleaner 线程,但它的并行效果完全依赖配置对齐。运行:
SELECT @@innodb_page_cleaners, @@innodb_buffer_pool_instances;
理想状态是两者相等(且 ≥ 4)。常见失配问题:
- 值都为
1:单线程刷所有实例,Buffer Pool 实例越多,争抢越激烈,page_cleaner循环必然超时 -
innodb_page_cleaners > innodb_buffer_pool_instances:MySQL 会自动截断为后者值,但配置本身暴露了调优意图未落实 - 两者都远大于物理 CPU 核心数(比如设为 16,但机器只有 4 核):线程上下文切换开销反噬性能,
page_cleaner反而更慢
调整时务必同步修改:innodb_page_cleaners 应等于 innodb_buffer_pool_instances,且不超过 CPU 核心数 × 2(保守起见建议 ≤ 核心数)。
排查底层 I/O 和内存资源是否真实不足
Page Cleaner 卡住,90% 情况下不是 MySQL 配置问题,而是硬件层撑不住。重点验证:
- 磁盘 I/O 等待:用
iostat -x 1查%util和await—— 若%util ≈ 100%或await > 50ms,说明磁盘已饱和,Page Cleaner 在排队等写入 - 内存压力:用
free -h和cat /proc/meminfo | grep -i "swapped\|commit"—— 若SwapTotal非零且SwapFree接近 0,或Committed_AS远超物理内存,MySQL 的innodb_buffer_pool_size实际已被 OS 动态压缩,脏页根本刷不动 - Redo Log 空间逼仄:查
Log sequence number和Last checkpoint at差值(在SHOW ENGINE INNODB STATUS中),若差值逼近innodb_log_file_size × 2,会强制触发 aggressive flush,拖垮 Page Cleaner
最容易被忽略的一点:Page Cleaner 日志延迟,往往发生在业务低峰期(比如凌晨 2 点),因为那时批量作业集中刷脏,而运维习惯性忽略夜间日志 —— 等白天报警,系统早已雪崩。盯住 took 字段,比等 crash 早三天发现问题。


















