mysql卡但cpu低时90%是swap导致:先用vmstat 1查si/so是否持续>1000 kb/s,再结合free -h确认swapused上涨;需调vm.swappiness=1、配置memlock无限并启用innodb_use_sys_malloc=0。

MySQL卡但CPU很低?90%是Swap在拖后腿,不是SQL慢、不是锁争用,而是内存页正被疯狂换入换出。
先确认si/so是否持续非零
别看top里mysqld的%Cpu,也别急着查慢日志——先跑vmstat 1盯住si(swap-in)和so(swap-out)两列:
- 单位是KB/s,只要任一值稳定 >1000,就已严重异常
- 配合
free -h看SwapUsed是否持续上涨,哪怕只涨几十MB -
swpd > 0+si/so > 0同时成立,基本可锁定Swap问题 - 注意:
used内存高不危险,available持续低于1G才真危险
检查vm.swappiness是否设成60这种“高危值”
执行sysctl vm.swappiness,如果输出是60或更高,说明内核正积极把InnoDB Buffer Pool里的热数据页往磁盘推:
- vm.swappiness=60意味着:物理内存使用率刚过40%,内核就可能开始换页
- 它不反映当前Swap是否在用,只控制“倾向”,所以
free -h显示SwapUsed=0也不代表安全 - 生产MySQL服务器建议压到
1~10之间;1最激进,10留点弹性 - 设成
0≠禁止Swap,只是推迟到OOM前最后一刻才启用,风险仍在
临时调低swappiness并验证效果
线上不能等重启,立刻执行:
-
sudo sysctl vm.swappiness=1(立即生效) - 再跑
vmstat 1观察si/so是否快速归零、响应是否明显恢复 - 若有效,写入
/etc/sysctl.conf固化:echo "vm.swappiness=1" >> /etc/sysctl.conf && sysctl -p - 云主机(如Ubuntu 20.04+)还要确认Swap设备是否真关了:
swapon --show输出为空才算
别只调swappiness,memlock才是根治关键
swappiness只是降低倾向,真正让mysqld进程免疫Swap,得靠memlock:
- 在
/etc/security/limits.conf加两行:mysql hard memlock unlimited和mysql soft memlock unlimited - 在
my.cnf的[mysqld]段加:innodb_use_sys_malloc=0(尤其配jemalloc时) - 必须由root启动mysqld(systemd下检查
LimitMEMLOCK是否生效) - 启动失败常见原因:
innodb_buffer_pool_size超物理内存70%,或/proc/mysqld_pid/status里CapBnd不含cap_ipc_lock
swappiness调低能快速缓解,但不配memlock,只要系统内存压力突增,mysqld仍可能被换出一页——Buffer Pool的LRU链表就全乱套,响应毛刺躲不掉。











