直接看Innodb_buffer_pool_wait_free(非零说明等空闲页)和Innodb_buffer_pool_pages_dirty(持续超70%总页数表明脏页积压),再结合Innodb_data_fsyncs与Innodb_data_writes比值偏低,可确认刷脏页压力大;innodb_io_capacity设过低会限制后台刷页速度,导致脏页堆积、强制同步及瞬时卡顿。

show global status 里哪些指标暴露刷脏页压力
直接看 Innodb_buffer_pool_wait_free 和 Innodb_buffer_pool_pages_dirty。前者非零说明线程在等空闲页,后者持续高位(比如 > buffer pool 总页数的 70%)说明脏页积压严重。再配合 Innodb_data_fsyncs 和 Innodb_data_writes 的比值——如果 fsync 次数远低于 write 次数,说明刷盘动作被延迟了,不是没写,是卡在落盘环节。
为什么 innodb_io_capacity 设置过低会拖慢刷脏页
这个参数告诉 InnoDB「每秒最多能刷多少页」,它直接影响后台线程刷脏页的节奏。默认值是 200,对 SSD 来说太保守;如果磁盘 I/O 实际能跑 2000+ IOPS,但这里还设成 200,InnoDB 就会主动压低刷新速度,导致脏页越积越多,最终触发强制同步(比如 redo log 满),造成瞬时卡顿。
- 查当前值:
SHOW VARIABLES LIKE 'innodb_io_capacity'; - SSD 环境建议设为 1000–4000,HDD 建议 200–500
- 改完要重启或动态设置:
SET GLOBAL innodb_io_capacity = 2000;
如何确认是不是 redo log 写满触发的连坐式刷脏页
当 innodb_log_file_size 太小、并发更新又高时,redo log 很快写满,MySQL 不得不暂停所有写操作,集中刷一批脏页来腾出空间——这就是最典型的“连坐”场景,表现为偶发性、持续几秒到十几秒的全库卡顿。
- 查日志是否频繁切换:
SHOW ENGINE INNODB STATUS\G里搜Log sequence number和Last checkpoint at,差值过大(比如 > 80% of log file size)就是预警信号 - 检查当前配置:
SHOW VARIABLES LIKE 'innodb_log_file_size'; - 生产环境单个 log 文件建议 ≥ 1GB,总大小(
innodb_log_files_in_group× 单文件大小)至少占 buffer pool 的 25%
buffer pool 实例数不足也会加剧刷脏页延迟
脏页链表(flush_list)是全局一把锁管理的。如果 innodb_buffer_pool_instances 还是默认的 1,所有刷脏页请求都排队抢同一把锁,尤其在大 buffer pool(比如 32GB+)下,锁争用会让刷新变慢,甚至出现 buf_flush_list_mutex 等待。
- 必须满足:
innodb_buffer_pool_size是innodb_buffer_pool_instances×innodb_buffer_pool_chunk_size的整数倍 - 常见安全配比:buffer pool 8GB → instances=4;16GB → instances=8;32GB+ → instances≥16
- 改完需重启生效,且不能只调 instances,chunk_size 也要同步校准(默认 128MB)
SHOW PROCESSLIST 里看到一堆 updating 或 Writing to net 状态,或者监控里 io_write_time 突然飙升。真正要定位,得盯住 buffer pool 状态、redo log 使用率、I/O 配置三者的联动关系,而不是单独看某一个指标。


















