2G 内存服务器救命指南:手把手教你创建 Swap 交换区(实战避坑版)

前言
手里有一台 2GB 内存的小服务器,跑个 Docker、数据库或者 Java 应用,动不动就 OOM Killed(内存溢出被杀进程)?升级配置太贵,不升级又老挂机。

这时候,Swap(交换分区) 就是你的救命稻草。它的原理是用硬盘空间模拟内存。虽然速度比真内存慢很多,但它的核心作用只有一个:在内存耗尽时,让系统“慢一点”,而不是“直接死掉”

本文还原了一次真实的排查过程,特别针对 fallocate 命令在某些环境下失效的情况,提供了最稳妥的 dd 创建方案。


🚨 故障现场:内存告急,Swap 为零

用户:大佬救命!我的 2G 小服务器跑 OpenClaw 经常崩溃。我想加个 Swap,但是之前试了好几次都报错,显示 read swap header failed

专家:别急,我们先看看现在的内存状况。

用户

1
2
3
4
$ free -h
total used free shared buff/cache available
Mem: 1.6Gi 1.5Gi 100Mi 3.0Mi 400Mi 200Mi
Swap: 0B 0B 0B

你看,Swap 完全是 0。

专家:确实,物理内存一旦用完,Linux 内核就会触发 OOM Killer 杀掉占用最高的进程。我们需要创建一个 4GB 的 Swap 文件。
注意:很多教程只教用 fallocate 命令,但这个命令在某些文件系统(如部分 VPS 的 overlay 文件系统)上不支持,会导致后续格式化失败。为了稳妥,我们直接使用兼容性最好的 dd 命令。


🛠️ 实战步骤:稳健创建 Swap(避坑指南)

第一步:创建 Swap 文件(关键:使用 dd)

专家:我们先删除可能存在的损坏文件,然后用 dd 从零开始写入一个 4GB 的文件。

用户

1
2
3
4
5
6
7
8
9
10
# 1. 清理旧文件(如果有)
sudo rm -f /swapfile

# 2. 使用 dd 创建 4G 文件
# if=/dev/zero : 输入源是零
# of=/swapfile : 输出文件路径
# bs=1M : 每次写入 1MB
# count=4096 : 写入 4096 次 (1MB * 4096 = 4GB)
# status=progress : 显示进度条(这步很重要,因为 dd 默认不显示进度,像卡死了一样)
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress

专家(等待几十秒) 看到进度条跑完,出现命令提示符了吗?

用户:跑完了!显示 4096+0 records in/out,文件创建成功。

💡 知识点:为什么不用 fallocate
fallocate 是瞬间创建稀疏文件,速度快但不一定被所有文件系统支持作为 Swap。dd 是实打实地写零,虽然慢一点(几秒到几十秒),但兼容性 100%,是解决 mkswap 报错的终极方案。

第二步:设置权限与格式化(最容易报错的环节)

专家:文件有了,接下来两步顺序不能错:先改权限,再格式化。很多人直接 swapon 就会报 read swap header failed,就是因为少了格式化这一步。

用户

1
2
3
4
5
# 1. 设置权限:只有 root 可读写(安全必须)
sudo chmod 600 /swapfile

# 2. 格式化为 Swap 分区(这一步生成文件头)
sudo mkswap /swapfile

专家:留意输出信息。

用户

1
2
Setting up swapspace version 1, size = 4 GiB (4294967296 bytes)
no label, UUID=a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx

成功了!之前我就是漏了 mkswap 直接 swapon 才报错的。

第三步:启用 Swap

专家:现在可以启用了。

用户

1
sudo swapon /swapfile

专家:验证一下。

用户

1
2
3
4
$ free -h
total used free shared buff/cache available
Mem: 1.6Gi 1.5Gi 50Mi 3.0Mi 450Mi 150Mi
Swap: 3.9Gi 0B 3.9Gi

完美!Swap 已经上线,容量 3.9G。

第四步:设置开机自动挂载

专家:现在生效了,但重启会失效。我们要把它写入 /etc/fstab

用户

1
2
3
4
5
# 备份配置文件(好习惯)
sudo cp /etc/fstab /etc/fstab.bak

# 追加挂载配置
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

⚡ 核心优化:调整 Swappiness(拒绝卡顿)

用户:Swap 有了,但我怕它一上来就用硬盘,导致服务器卡成 PPT。

专家:非常有远见!Linux 默认策略比较激进(vm.swappiness=60),内存用到 40% 就开始换出到硬盘。对于小内存服务器,我们要让它**“不到万不得已,绝不动用 Swap”**。

我们将值改为 10(甚至 1):

用户

1
2
3
4
5
6
7
8
9
# 1. 临时生效(立即执行)
sudo sysctl vm.swappiness=10

# 2. 永久生效(写入配置)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

# 3. 可选:优化缓存压力
echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

专家:现在策略变了:

  • 以前:内存剩 60% 时就开始用 Swap(频繁读写硬盘,卡)。
  • 现在:内存几乎用光(剩 10% 以下)时,才慢慢启用 Swap(保命,平时不卡)。

📝 最终验收清单

执行完以上操作,你的服务器已经具备了“不死之身”。最后运行一次检查:

1
2
3
4
5
6
7
8
9
10
# 1. 确认 Swap 大小
free -h

# 2. 确认 Swappiness 参数
cat /proc/sys/vm/swappiness
# 输出应为 10

# 3. 确认 fstab 配置
grep swap /etc/fstab
# 输出应包含 /swapfile

💡 给 Docker 用户的额外建议

如果你主要跑 Docker,建议配合限制容器内存,效果更佳:

1
2
3
4
5
6
# docker-compose.yml 示例
services:
app:
image: your-image
mem_limit: 1500m # 限制容器最大 1.5G,留出 500M 给系统和缓冲
mem_reservation: 512m

结语

通过 dd 命令创建 Swap 是最稳妥的方案,彻底解决了 fallocate 在某些环境下的兼容性问题。配合 vm.swappiness=10 的优化,你的 2G 小服务器现在拥有了 4GB 的应急缓冲池

记住:Swap 的目的是防止崩溃,而不是提升性能。当系统开始大量使用 Swap 时,你会感觉到操作变慢,但这正是它在努力保护你的进程不被杀掉。

可以慢,但不能死! 这就是运维的底线。