innodb_io_capacity是innodb后台刷脏页和合并change buffer的节奏控制器,非硬盘极限iops;需用fio实测4k随机写iops并折算,ssd推荐设1000–3000,且必须配innodb_io_capacity_max=1.5~2倍,并调优io线程数与文件系统参数。

先看磁盘真实随机写IOPS,别信标称值
innodb_io_capacity 不是“硬盘能跑多快”,而是 InnoDB 后台刷脏页和合并 change buffer 的节奏控制器。设高了不加速写入,反而让 log file is full、Waiting for query cache lock 这类等待飙升——本质是后台刷得太猛,把 redo log 循环堵死了。
必须用 fio 实测你线上 SSD 在数据库负载下的稳定随机写能力:
fio --name=randwrite --ioengine=libaio --rw=randwrite --bs=4k --numjobs=1 --iodepth=32 --runtime=60 --time_based --direct=1 --filename=/path/to/ssd/testfile- 重点看输出里的
iops值(不是 MB/s),取最后 30 秒稳定平均值 - 消费级 NVMe(如致态 TiPlus7100、三星 980 Pro)实测常在 2.5 万~5 万 IOPS,但
innodb_io_capacity绝不能直接设成 5000
原因:InnoDB 每次刷的是 16KB page,而 fio 测的是 4K 随机写;且它只管后台任务,不参与前台事务日志写入(那是 innodb_log_file_size 和 innodb_flush_log_at_trx_commit 管的)。
SSD 上推荐值其实是 1000–3000,不是越高越好
中高端消费级 SSD(如三星 970 EVO、致态 TiPlus7100)生产环境设 2000 最稳妥;入门级(金士顿 A400、铠侠 RC20)建议 1000;NVMe 企业盘(Intel D3700、Solidigm D5-P5316)可上到 4000–6000,但必须配好 innodb_io_capacity_max。
常见误操作:
- 看到 SSD 标称 8 万 IOPS,就把
innodb_io_capacity设成 8000 → 结果Innodb_data_fsyncs每秒跌到个位数,Innodb_buffer_pool_pages_dirty长期卡在 80% 以上 - 只调这个参数,不查
/proc/diskstats→ 如果对应设备的await > 10ms或%util == 100%,说明磁盘已饱和,调参白忙 - 忽略
innodb_flush_method→ Linux 下必须是O_DIRECT,否则 OS 缓存层会干扰 InnoDB 对 IO 节奏的判断
必须成对配置 innodb\_io\_capacity\_max,且不能缺省
innodb_io_capacity_max 是弹性上限,不是摆设。当主库突发大事务、从库追延迟时,InnoDB 会临时冲高刷盘速度——没它兜底,就可能瞬间打爆 IO 队列,引发系统级延迟毛刺。
配置规则很明确:
-
innodb_io_capacity_max = innodb_io_capacity × 1.5~2(例如前者 2000,后者设 3000~4000) - 设为 0 或不设?InnoDB 会自动按
innodb_io_capacity × 2算,但不可控,线上严禁依赖 - 配套必须关掉 HDD 优化策略:
innodb_flush_neighbors = 0(SSD 上启用邻近页刷新纯属增加无效 IO)
线程数也要跟上:innodb_write_io_threads 和 innodb_read_io_threads 各设 4~8(默认 4),否则 IO 能力再强也调度不过来。
验证是否真生效,盯住三个地方
别只看 QPS 或 TPS,重点观察:
- 执行
SHOW ENGINE INNODB STATUS\G,翻到 “BUFFER POOL AND MEMORY” 段,看Pages flushed是否稳定——突增突降说明节奏失控 - 监控
Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests比值,低于 99.5% 就要警惕,但这通常不是innodb_io_capacity的问题,而是缓冲池太小或查询未走索引 - 确认 TRIM 已启用:
lsblk -D查Disc-GRAN和Disc-MAX是否非零;没启用就加discard=on到挂载选项并重启 MySQL,否则后台刷脏会反复写已标记删除的块
最常被忽略的一点:innodb_io_capacity 只影响后台 IO 调度节奏,不是 IO 加速器。如果磁盘本身 await 高、util 满,或者文件系统没配 noatime、data=writeback(ext4)或 logbufs=8(XFS),参数调得再准也没用。











