禁用Swap后MySQL仍可能触发swap,仅当swap未彻底关闭:swapoff -a为临时操作,若/etc/fstab未注释swap行或swap设备仍active,重启后自动挂载,内核仍可换出Buffer Pool匿名页。

禁用Swap不是为了“省磁盘”,而是防止MySQL在内存压力下被内核强制换出,引发性能断崖或直接OOM Kill。
swapoff 后 MySQL 还会触发 swap 吗?
会,但只有一种情况:你没真正关掉——swapoff -a 是临时的,重启后失效;/etc/fstab 里没注释 swap 行,系统启动时又自动挂载了。验证是否彻底关闭:
- 运行
swapon --show,输出为空才表示没启用 - 检查
free -h中 swap 行 total 为 0 - 确认
/proc/swaps是空文件
只要 swap 设备还存在且 active,Linux 内核就可能把 MySQL 的 Buffer Pool(匿名页)换出,哪怕你设了 innodb_flush_method=O_DIRECT ——它只绕 page cache,不保 Buffer Pool 驻留。
为什么 MySQL 的 swap 行为特别危险?
MySQL 的 Buffer Pool 是大块匿名内存页,内核回收时优先 swap 这类页。一旦开始 swap:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
-
vmstat 1中so(swap out)持续非零,说明正在换出 -
cat /proc/vmstat | grep pgpgout增长加快,证实匿名页被刷盘 - 查询响应时间突增 10 倍以上,慢日志里大量
Creating sort index或Copying to tmp table - 最坏情况:OOM Killer 观察到 mysqld RSS 最高,直接
kill -9
云主机默认常关 swap,但物理机/VM 容易遗漏;Kubernetes 节点若未禁用 swap,Pod 里的 MySQL 一样会中招。
禁用 swap 后内存不够怎么办?
禁用 swap 不等于放弃内存管理,而是逼你做真实容量规划:
-
innodb_buffer_pool_size必须按MemAvailable(不是free -h的 free)算,保守取 ≤60% -
tmp_table_size和max_heap_table_size建议统一设为64M,防大 JOIN 创建巨型内存临时表 - 必须配 cgroup 硬限:
systemctl set-property mysqld.service MemoryMax=3G,否则 mysqld 仍会按宿主机内存估算 buffer pool - 查
SHOW GLOBAL STATUS LIKE 'Created_tmp%tables',若Created_tmp_disk_tables持续增长,说明 SQL 已落地磁盘临时表——该优化语句,不是加内存
真正容易被忽略的是:NUMA 架构下,即使 swap 关了,Buffer Pool 若跨 node 分配不均,node 0 耗尽后也会触发本地 swap 或 OOM。所以 numactl --interleave all 或 innodb_numa_interleave = ON 不是可选项,是 NUMA 服务器上的必选项。










