mysql在vmware中iops上不去,首要排查磁盘控制器(禁用ide,改用lsi logic sas或pvscsi)和磁盘类型(改用thin provisioned),并确认存储策略启用ssd缓存;其次检查innodb_buffer_pool_size是否过高导致swap、innodb_flush_method是否为o_dsync、esxi层iops limits是否合理配置。

MySQL在VMware里IOPS上不去,先看磁盘控制器和磁盘类型
VMware默认给新建虚拟机配IDE控制器+厚置备磁盘,这两项直接锁死IOPS上限——IDE控制器单队列、无NCQ,厚置备磁盘又浪费空间且影响快照性能。真实压测中,同样一块SSD后端存储,IDE控制器下sysbench io read跑不出5K IOPS,换成LSI Logic SAS能到80K+。
必须改三项:
- 控制器类型:在VM设置里删掉IDE硬盘,添加新硬盘时选
LSI Logic SAS或VMware Paravirtual(后者对高并发写更友好) - 磁盘类型:新建磁盘选
Thin Provisioned,不是“厚置备延迟置零” - 存储策略:如果用vSAN或FusionCube,确认该LUN已启用
SSD缓存层,且未被其他VM抢占(查vCenter里Storage I/O Control面板)
innodb_buffer_pool_size设太高反而拖慢IOPS
常见误区是把innodb_buffer_pool_size设成虚拟机内存的75%,结果OS频繁swap,iostat -x 1里%util飙到100%但r/s和w/s很低——本质是内存换页引发大量小IO。
正确做法是留足余量:
- 虚拟机总内存为16GB → OS至少留1.5GB → MySQL可用缓冲池上限≈11GB(即68%)
- 若观察到
Innodb_buffer_pool_wait_free持续非零,说明buffer pool太小,page clean跟不上,会触发强制刷脏页,产生突发写IO - 用
SHOW ENGINE INNODB STATUS\G检查BUF BUFFER POOL段,确认Free buffers不长期为0
写缓存模式不调,MySQL的fsync就是硬伤
MySQL默认每秒刷一次innodb_log_file_size大小的redo log,但VMware虚拟磁盘默认透写(Write-Through),每次fsync()都落到物理盘,延迟直接拉高到20ms以上。实测把innodb_flush_method从fsync改成O_DSYNC,TPS提升40%,且avgqu-sz下降明显。
但改之前必须确认两件事:
- 宿主机存储的电池/电容模块状态正常(FusionCube界面看
Cache Battery Health是否OK) - 虚拟机内禁用
vmware-tools的disk.enableUUID(避免元数据冲突) - 配置文件加这三行:
innodb_flush_method = O_DSYNC<br>innodb_use_native_aio = ON<br>innodb_io_capacity = 2000
(数值按后端SSD实测IOPS的1/3设,比如NVMe实测300K,这里填1000)
ESXi层IOPS限制和QoS别漏设
就算MySQL和存储都调好了,VMware资源调度层没管住,一台测试库突然跑个mysqldump --all-databases就能把整个集群IO打满。vCenter里必须关机状态下操作:
- 进VM设置→硬盘→
Limits - IOPS:设硬上限,比如MySQL生产VM填8000,备份VM填2000 - 若用Storage Policy,绑定策略时勾选
IOPS Limit并指定值,比单VM设置更易批量管控 - 警惕
Shares设成High却不设Limits——这等于告诉ESXi“我要抢光所有IO”,其他VM会卡顿
真正卡点不在MySQL参数,而在VMware存储栈的每一层是否对齐:控制器驱动、缓存策略、IO调度器、ESXi资源限制,漏掉任何一层,IOPS都会断崖下跌。











