是,innodb_lru_scan_depth 设置过高会卡住刷脏页;它导致每次刷脏前必须扫描大量页面,在高并发下引发锁争用、拖慢刷脏节奏,造成脏页堆积和tps下降。

innodb_lru_scan_depth 设置太高会卡住刷脏页吗
会,而且非常容易卡。这个参数控制的是 InnoDB 每次做 LRU 列表扫描时,最多检查多少个 page 来找可淘汰的脏页——但它不是“只扫这么多”,而是“每次刷脏前都得扫完这么多”。如果设成默认值 1024(甚至更高),在高并发写入场景下,InnoDB 可能频繁陷入长耗时的扫描,导致 log_flush_order_mutex 或 buf_pool_mutex 等关键锁争用加剧,进而拖慢整个刷脏节奏,看起来就像“脏页堆积、Redo 日志写满、TPS 突降”。
实操建议:
- 生产环境建议从
innodb_lru_scan_depth = 256起步,SSD 机器可试512;机械盘务必压到128或更低 - 观察
SHOW ENGINE INNODB STATUS中的BUF_POOL_LRU_SCAN_DEPTH实际扫描耗时(在 BUFFER POOL AND MEMORY 小节里) - 配合
innodb_io_capacity和innodb_io_capacity_max调整,避免扫描深度远超磁盘实际吞吐能力
为什么调低 innodb_lru_scan_depth 反而能加快脏页刷新
这不是“少干活”,而是“更准地干活”。InnoDB 刷脏的核心瓶颈从来不是“找不到脏页”,而是“在大量干净页里盲目翻找脏页”。innodb_lru_scan_depth 值越大,越容易在 LRU 列表冷端反复扫描大量干净页(尤其在写入热点集中时),浪费 CPU 且延迟真正需要刷出的热脏页。
实操建议:
- 降低该值后,InnoDB 更依赖
buf_flush_list(按修改顺序组织的脏页链表)来驱动刷脏,这才是高效路径 - 确保
innodb_adaptive_flushing = ON(默认开启),让系统根据redo log使用率自动调节刷脏频率,而不是死磕 LRU 扫描 - 监控
Innodb_buffer_pool_pages_dirty和Innodb_os_log_pending_fsyncs,若前者持续升高、后者也上升,说明刷脏已滞后,需同步检查innodb_io_capacity是否过低
innodb_lru_scan_depth 和 innodb_io_capacity 的协同关系
这两个参数是“扫描节奏”和“写入能力”的配对开关。单独调低 innodb_lru_scan_depth 而不提升 innodb_io_capacity,可能导致刷脏总量跟不上写入速度;反之,盲目拉高 innodb_io_capacity 却保留超高 innodb_lru_scan_depth,只是让 CPU 更忙、IO 更乱。
实操建议:
-
innodb_io_capacity应基于磁盘真实随机写 IOPS 设定:NVMe 盘常见 3000–10000,SATA SSD 常见 500–2000,HDD 建议 100–200 -
innodb_lru_scan_depth推荐值 ≈innodb_io_capacity / 4(上限不超过 1024),例如innodb_io_capacity = 2000→innodb_lru_scan_depth = 512 - 动态调整时,优先改
innodb_io_capacity(在线生效),再微调innodb_lru_scan_depth(需重启或 SET GLOBAL,部分版本支持在线)
哪些现象说明你被 innodb_lru_scan_depth 坑了
不是所有刷脏慢都怪它,但以下组合出现时,十有八九是它在捣鬼:
- 慢查询日志里大量语句卡在
waiting for handler commit或updating status,同时SHOW PROCESSLIST显示很多线程状态为Writing to net或Freeing items -
SHOW ENGINE INNODB STATUS中 “BUFFER POOL AND MEMORY” 下的LRU len很大(比如 >50w),但free buffers长期接近 0,database pages却没涨——说明 page 在 LRU 里“滞留不动” - Percona Toolkit 的
pt-stalk抓到buf_pool_mutex等待时间突增,且与innodb_lru_scan_depth值正相关
真正难处理的是:这个问题在低负载时完全不暴露,一到业务高峰就间歇性抖动,且不像锁等待那样有明确堆栈。调参前务必用 pt-pmp 或 perf 抓一次火焰图,确认热点是否真落在 buf_LRU_search_and_free_block 上。











