MySQL在SSD上未提速,主因是InnoDB参数仍沿用HDD配置:需关闭I/O调度器(NVMe设none、SATA SSD设noop),实测调优innodb_io_capacity(建议值=实测随机写IOPS×0.7~0.8),设innodb_flush_neighbors=0,innodb_buffer_pool_size按available内存×0.7设定,避免OOM,并确保innodb_log_file_size总和≈buffer_pool_size×0.25。

MySQL在SSD上没变快,大概率是InnoDB参数还按HDD那一套配的——不是硬件不行,是配置没对上闪存的物理特性。
为什么关I/O调度器是第一步
SSD不靠磁头寻道,Linux默认的cfq或deadline调度器反而会引入额外排队和延迟。NVMe盘必须切到none,SATA SSD用noop。
- 查当前调度器:
cat /sys/block/nvme0n1/queue/scheduler(把nvme0n1换成你的真实设备名) - 临时生效:
echo none > /sys/block/nvme0n1/queue/scheduler - 永久生效要改
/etc/default/grub,加elevator=none,再update-grub && reboot - 云主机或容器里可能无法直接改,得确认宿主机是否已调好
innodb_io_capacity不能照搬文档值
这个参数控制InnoDB后台刷脏页、合并change buffer的IO强度上限。设太高会打满SSD带宽,拖慢查询;设太低则脏页堆积,最终照样卡住。
- 别信“SSD设成2000~10000”这种模糊建议,先实测:用
fio跑--name=randwrite --ioengine=libaio --bs=16k --iodepth=64 --runtime=60 - 生产值 = 实测随机写IOPS × 0.7~0.8(留余量),例如实测120K →
innodb_io_capacity = 90000 -
innodb_io_capacity_max设为innodb_io_capacity × 2,应对突发负载 -
innodb_flush_neighbors = 0必须开,SSD不需要预取相邻页,关了能稳提15%+性能
innodb_buffer_pool_size调太大真会OOM
SSD降低了IO等待,但内存压力一点没少。Buffer Pool占太多,系统缓存、连接线程、其他进程就容易被OOM killer干掉,尤其在小内存服务器上。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 看真实可用内存:
free -h里的available列,不是total - used - 安全上限 ≈
available× 0.7,比如available是30G →innodb_buffer_pool_size = 21G - 如果开了
innodb_buffer_pool_instances > 1,确保buffer_pool_size能被整除,否则多余内存会被丢弃 - 持续看到
Innodb_buffer_pool_wait_free非零,说明Buffer Pool不够用,或并发写入太猛
innodb_log_file_size和同步策略别乱动
SSD的fsync延迟低,但不代表可以牺牲数据安全性。日志文件大小和刷盘策略影响的是崩溃恢复时间与数据持久性边界。
-
innodb_log_file_size总和(所有log file)建议 =innodb_buffer_pool_size× 0.25,比如Buffer Pool 21G → 总log大小≈5G(两个文件各2.5G) -
sync_binlog = 1和flush_log_at_trx_commit = 1仍应保持,除非业务明确接受秒级数据丢失风险 -
innodb_log_buffer_size可设为128M~256M,避免大事务反复刷日志缓冲区
真正容易被忽略的是:SSD性能优势只在随机IO密集场景下才明显。如果你的Buffer Pool已经能把热数据全缓住,那换SSD也看不出差别——先确认是不是真在跑随机IO,再调参。










