关闭swap需分步验证与兜底:先确认进程swap占比超5%~10%,再执行swapoff -a并注释fstab;同步绑定cgroups内存硬限、调vm.swappiness=1、设数据库内存淘汰策略及buffer pool上限,最后压测验证majflt趋近于0且无oom日志。

在生产环境高并发数据库集群中,关闭 Swap 不是“一刀切”的操作,而是一套需验证、分步、带兜底的配置流程。盲目执行 swapoff -a 可能导致 OOM Killer 立即杀掉数据库进程(如 Redis、MySQL、GBase),尤其当 maxmemory 未合理设置或内存工作集接近物理上限时。
先确认 Swap 是否真在影响数据库
别跳过这一步——多数卡顿并非 Swap 导致,而是 AOF rewrite、RDB fork、LFU 衰减、NUMA 内存不均衡或 Page Cache 压力引发。
- 用
redis-cli info | grep process_id或pgrep -f "mysqld|postgres"拿到主进程 PID - 运行
cat /proc/<pid>/status | grep -i swap</pid>,检查 Swap 字段是否 > 0(注意不是 SwapPss) - 进一步统计换出比例:
cat /proc/<pid>/smaps | awk '/^Size:/ {size+=$2} /^Swap:/ {swap+=$2} END {printf "Swap ratio: %.1f%\n", swap/size*100}'</pid>
若长期高于 5%~10%,才说明存在真实 Swap 压力
安全关闭 Swap 的两步法
仅禁用 Swap 不够,必须同步建立内存硬限与回收缓冲机制,防止内核在无 Swap 时直接触发 OOM。
-
第一步:临时关闭 + 永久屏蔽
执行sudo swapoff -a,同时注释/etc/fstab中所有 swap 行(如# /dev/sdb1 none swap sw 0 0) -
第二步:绑定 cgroups v2 内存上限
例如为 MySQL 创建内存约束:mkdir -p /sys/fs/cgroup/db-mysqlecho 12G > /sys/fs/cgroup/db-mysql/memory.maxecho $(pgrep mysqld) > /sys/fs/cgroup/db-mysql/cgroup.procs
这样即使 RSS 突增,也不会突破硬限,避免 OOM 杀进程
配套内核与数据库参数调优
关 Swap 后,系统更依赖内存管理策略的合理性,以下参数必须同步调整:
-
vm.swappiness = 1(非 0):文档明确说明=0仅“尽可能避免” Swap,但不禁止;=1才真正抑制匿名页换出,同时保留极小弹性,防 OOM 误判 - 数据库侧设淘汰策略:Redis 必须配
maxmemory-policy allkeys-lfu或volatile-lru,不能只写maxmemory;MySQL 需确认innodb_buffer_pool_size≤ 物理内存 × 0.7,并开启innodb_numa_interleave=ON(防 NUMA 引发局部 Swap) - 禁用大页前先验证:若启用
vm.nr_hugepages,务必确保应用实际使用(如 PostgreSQL 需huge_pages = on),否则空占内存反而加剧压力
上线前必做的压测验证
关闭 Swap 后,必须模拟高峰期内存压力,验证两点:
- 在
free -h显示可用内存降至 1–2GB 时,数据库是否仍响应正常、无连接超时、无 OOM 日志 - 用
pidstat -r 1观察进程%mem和minflt/majflt:majflt(主缺页)应趋近于 0,说明无页面换入;若持续 > 50/sec,说明仍有隐性 Swap 活动或内存碎片问题











