MySQL 5.7高并发下CPU单核满载源于Buffer Pool全局锁竞争,根本原因是innodb_buffer_pool_instances=1时所有线程争抢同一把buf_pool_mutex,导致执行串行化;需设为8或与CPU核数对齐,并确保buffer pool size满足chunk_size×instances整除,否则向上取整易引发OOM。

innodb_buffer_pool_instances = 1 是最常见诱因
Buffer Pool 默认只开 1 个实例(innodb_buffer_pool_instances = 1)时,所有线程访问缓存页都必须抢同一把 buf_pool_mutex。即使只是 SELECT 查询,只要涉及页查找、LRU 管理或 free list 维护,就卡在这里。
- 现象:
SHOW ENGINE INNODB STATUS\G的 SEMAPHORES 段里频繁出现RW-latch created in file buf0buf.cc - 验证:查
SELECT @@innodb_buffer_pool_instances;,若为 1,且innodb_buffer_pool_size > 1G,基本就是它 - 修复:设为 8(或按核数对齐,如 16 核设 16),但必须同步满足 chunk 对齐约束:
innodb_buffer_pool_size必须是innodb_buffer_pool_chunk_size × instances的整数倍,否则会向上取整引发 OOM
innodb_read_io_threads 和 innodb_write_io_threads 不影响 CPU 核心利用率
这两个参数只控制后台 IO 线程数(如预读、刷脏页),不参与用户查询的执行路径。高并发 SELECT 的瓶颈不在 IO 调度,而在内存结构争用——所以调高它们对缓解单核瓶颈无效。
-
innodb_read_io_threads默认 4,仅用于异步读取物理页,不参与 SQL 解析、索引查找、缓冲池哈希定位 - 真正决定读请求能否并行的是 buffer pool 实例锁、adaptive hash index latch、甚至
dict_sys->mutex(当表元数据频繁访问时) - 不要误以为“开了 8 个 io 线程,读就能打满 8 核”——这是典型混淆 IO 并发与查询执行并发
adaptive hash index latch 在高并发等值查询时成新热点
当大量 SELECT 都走相同二级索引等值查询(如 WHERE status = 'paid'),InnoDB 会自动构建 AHI 加速,但 AHI 的全局 latch(btr_search_latch)就成了新瓶颈。
- 现象:
SHOW ENGINE INNODB STATUS\G中 SEMAPHORES 出现大量wait array slot等待,且文件名含btr0sea.cc - 临时缓解:设
innodb_adaptive_hash_index = OFF(MySQL 5.7.20+ 支持动态关闭) - 长期方案:确认是否真需要 AHI——如果查询模式高度固定,可改用覆盖索引;若写入频繁,AHI 维护开销反而抵消收益


















