mysql在vmware中卡顿的根源是虚拟层资源调度隐藏问题,需优先排查vcpu ready time(持续>5%即存在调度等待)、内存ballooning(>512mb即危险)和存储i/o栈(默认fsync导致双缓冲延迟),而非直接调优mysql参数。

不是MySQL本身变慢了,而是虚拟层把资源调度“藏”起来了——直接调参数不解决问题,得先看清vCPU Ready Time、内存ballooning、存储I/O栈这三道墙。
查vCPU Ready Time:别只看top里的CPU%
ESXi里top显示mysqld占90% CPU,但实际可能在排队等物理核。真正瓶颈是vCPU就绪延迟,不是计算能力不足。
- 用
esxtop按c进入CPU视图,盯住RDY%列:持续 >5% 就说明vCPU经常等资源,哪怕宿主机CPU空闲 - 避免给MySQL VM分配过多vCPU(比如8vCPU),尤其当物理核少于4个时——vCPU越多,调度越难对齐,
RDY%飙升更快 - 真要高并发,宁可开2台4vCPU的VM,也别塞1台8vCPU;配合
cpuid.coresPerSocket=4显式设socket数,让ESXi NUMA调度更准
防内存ballooning:innodb_buffer_pool_size不是越大越好
MySQL启动失败或缓冲池命中率暴跌,常因VM被宿主机“抽走”内存——vmware-toolbox-cmd stat balloon返回值 >512MB 就危险了。
- 设
innodb_buffer_pool_size前,先跑free -h看available列,不是free列;建议 ≤ available × 0.6 - 关掉Linux的
swappiness(设为1),避免内核主动换出MySQL进程页,触发balloon driver介入 - ESXi端禁用memory balloon:编辑VM设置 →
Mem.MemZeroEnable = FALSE+Mem.AllocGuestLargePage = FALSE(需关机修改)
绕过虚拟存储双缓冲:innodb_flush_method必须改
默认fsync在VMware里会触发两次刷盘(guest OS + hypervisor),写延迟动辄破100ms。这不是磁盘慢,是路径冗余。
- Linux VM上强制设
innodb_flush_method = O_DIRECT,跳过OS page cache,直写虚拟磁盘后端 - 验证是否生效:
strace -p $(pgrep mysqld) -e trace=write,fsync,pwrite64 2>&1 | grep -E "(fsync|O_DIRECT)",看到O_DIRECT标志才算落地上 - 别碰
async_unbuffered(已废弃)或留空(等价fsync);XFS文件系统下O_DIRECT比O_DSYNC更稳
主从延迟和连接堆积:时间漂移与休眠残留
虚拟机暂停/迁移后恢复,MySQL复制延迟暴增、Sleep连接卡死,根源是系统时间跳变+连接状态不同步。
- 停掉
systemd-timesyncd或ntpd,启用vmtoolsd --timesync-enable,让宿主机统一授时 -
wait_timeout必须设≤300(5分钟),否则休眠唤醒后大量Sleep连接占满max_connections -
slave_net_timeout = 30,配合MASTER_HEARTBEAT_PERIOD = 10,避免网络抖动误判为断连
所有调优都得在performance_schema打开的前提下做——没它,你看到的只是表象;开了它,才能定位到wait/io/file/innodb/innodb_data_file这类真实I/O等待事件。虚机环境里,配置改得再猛,不如先看清资源到底卡在哪一层。











