mysql如何排查由于SWAP导致的数据库卡顿_mysql系统级性能排查

1次阅读

mysql卡顿但cpu不高时,大概率是swap被疯狂使用;需用free -h和vmstat 1检查swapused、si/so值,确认后通过drop_caches、调低swappiness、配置memlock和o_direct根治。

mysql如何排查由于SWAP导致的数据库卡顿_mysql系统级性能排查

MySQL卡顿但CPU不高,先看SWAP是否被疯狂使用

很多dba第一反应是查CPU或慢查询,但MySQL卡成PPT、select 1都超时,而topmysqld的%CPU却只有10%——这时候90%概率是SWAP在拖后腿。linux内核一旦开始频繁换页(swap in/out),所有内存访问都会变成磁盘IO,MySQL这种重度内存依赖的服务会直接“窒息”。

  • free -hSwapUsed 是否持续 >1GB;更关键的是看 si(swap-in)和 so(swap-out)列,单位KB/s,只要这两个值 >1000 就已严重异常
  • vmstat 1 中若 swpd > 0 且 si/so 长期非零,基本可锁定SWAP问题
  • 别信used内存高就一定爆了——buff/cache高是健康表现,真正危险的是available持续低于1G且swpd上涨

临时止血:快速清空SWAP并防止立刻复用

线上不能等重启,得先让MySQL喘口气。但swapoff -a不是万能解药——它会把SWAP里所有页强行刷回物理内存,如果此时内存已不足,直接触发OOM Killer干掉mysqld进程。

  • 执行前务必确认可用内存:awk '/MemAvailable/{print $2/1024/1024 " GB"}' /proc/meminfo,确保结果 > SWAP已用量
  • 安全清SWAP顺序:swapoff -a && swapon -a(仅当内存充足时);否则改用echo 1 > /proc/sys/vm/drop_caches先释放pagecache,再尝试
  • 立即压制换页冲动:sysctl vm.swappiness=0(临时),并写入/etc/sysctl.conf固化,避免下次重启复发

根治方案:让MySQL彻底告别SWAP

只关swappiness是治标。MySQL进程本身必须被禁止换出,否则内核仍可能在内存压力下把它踢进SWAP——哪怕只换出一页,InnoDB Buffer Pool的LRU链表就全乱套。

  • /etc/security/limits.conf追加两行:mysql hard memlock unlimitedmysql soft memlock unlimited
  • my.cnf[mysqld]段加入:innodb_flush_method=O_DIRECT(绕过OS缓存,减少内存争抢)
  • 重启MySQL前,检查是否生效:prlimit -p $(pgrep mysqld) | grep memlock,输出应为unlimited
  • 注意:开启memlock后,innodb_buffer_pool_size不能设超过物理内存70%,否则mysqld启动会失败

容易被忽略的陷阱:大页内存与配置冲突

有人开了memlock还卡,一查发现启用了large_pages但没配hugepage,结果MySQL启动时默默退回到普通页+SWAP模式,表面配置全对,实际毫无作用。

  • 检查是否真用了大页:grep -i huge /proc/meminfo,看HugePages_Free是否 >0
  • 若启用large_pages=ON,必须提前分配hugepage:echo 2048 > /proc/sys/vm/nr_hugepages(按需调整数值)
  • 更稳妥的做法:先禁用large_pages,专注把memlock+O_DIRECT+swappiness=0三件套跑通,再考虑大页优化

SWAP问题最狡猾的地方在于:它不报错,只让一切变慢。监控里看不到Error,日志里没有WARNING,连SHOW PROCESSLIST都显示“Sleep”,但你的业务请求正在排队等IO。盯住si/somemlock状态,比优化一百条SQL都管用。

text=ZqhQzanResources