Linux 交换分区Swap详解与配置

2021-08-10 Linux 运维

前言

Swap(交换分区)是 Linux 系统中重要的内存管理机制,当物理内存不足时,系统会将部分不活跃的内存页交换到磁盘上的 Swap 空间,从而避免 OOM(Out of Memory)导致进程被杀死。本文将详细介绍 Swap 的原理、创建方法、swapon 命令、swappiness 参数调优,以及永久挂载配置。

1. Swap 基础概念

1.1 什么是 Swap

Swap 是 Linux 的虚拟内存机制,有以下两种形式:

类型 说明 优点 缺点
Swap 分区 独立的磁盘分区 性能较好 需要预先分区
Swap 文件 文件系统上的文件 灵活,可动态调整 性能略差

1.2 Swap 的作用

  1. 扩展内存容量:当物理内存不足时,提供额外的"内存"空间
  2. 内存回收:将不活跃的内存页换出,释放物理内存给活跃进程
  3. 休眠支持:系统休眠(hibernate)需要将内存数据写入 Swap
  4. 避免 OOM:防止内存耗尽导致进程被 OOM Killer 杀死

1.3 Swap 与物理内存对比

特性 物理内存(RAM) Swap(磁盘)
速度 纳秒级(~10ns) 毫秒级(~10ms)
断电数据 丢失 持久保存
成本 高 低
用途 活跃数据 不活跃数据

重要:Swap 不是物理内存的替代品!由于磁盘速度远慢于内存,过度依赖 Swap 会导致系统性能严重下降(swap thrashing)。

2. 查看当前 Swap 状态

2.1 使用 free 命令

# 查看内存和 Swap 使用情况
free -h

# 输出示例:
#               total        used        free      shared  buff/cache   available
# Mem:           7.8G        2.1G        1.2G        108M        4.5G        5.3G
# Swap:          2.0G          0B        2.0G

字段说明:

  • total:总大小
  • used:已使用
  • free:完全空闲
  • available:实际可用(考虑 buff/cache 可回收)

2.2 使用 swapon 命令

# 查看 Swap 使用情况
swapon --show

# 详细输出
swapon -v

# 输出示例:
# NAME      TYPE      SIZE USED PRIO
# /swapfile file        2G   0B   -2

2.3 查看 /proc/swaps

cat /proc/swaps

# 输出示例:
# Filename              Type        Size    Used    Priority
# /swapfile                               file      2097148 0   -2

2.4 使用 top / htop 查看

# top 命令(按 f 键可添加 Swap 列)
top

# htop 命令(更直观)
htop

3. 创建 Swap 文件(推荐方式)

Swap 文件比分区更灵活,可以随时调整大小,适合云服务器和虚拟机。

3.1 创建 Swap 文件的完整步骤

# 1. 创建 Swap 文件(以 2G 为例)
# bs=1M count=2048 表示 1M * 2048 = 2048M = 2G
dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress

# 或使用 fallocate(更快,但某些文件系统不支持)
fallocate -l 2G /swapfile

# 2. 设置正确的权限(非常重要!)
chmod 600 /swapfile

# 3. 格式化 Swap 文件
mkswap /swapfile

# 4. 启用 Swap
swapon /swapfile

# 5. 验证
swapon --show
free -h

3.2 dd 与 fallocate 的区别

命令 原理 速度 兼容性
dd 逐块写入零 较慢 所有文件系统
fallocate 预分配空间(不写入) 极快 ext4, xfs(不支持 Btrfs)

注意:某些文件系统(如 Btrfs、F2FS)不支持 fallocate,必须使用 dd。

3.3 不同大小的 Swap 文件创建

# 1G Swap
dd if=/dev/zero of=/swapfile bs=1M count=1024

# 4G Swap
dd if=/dev/zero of=/swapfile bs=1M count=4096

# 8G Swap
dd if=/dev/zero of=/swapfile bs=1M count=8192

# 16G Swap
dd if=/dev/zero of=/swapfile bs=1M count=16384

4. 创建 Swap 分区

如果服务器有独立的磁盘分区可用作 Swap,性能通常优于 Swap 文件。

4.1 使用 fdisk 创建 Swap 分区

# 1. 查看磁盘
fdisk -l

# 2. 对目标磁盘进行分区(以 /dev/sdb 为例)
fdisk /dev/sdb

# 在 fdisk 交互界面:
# n - 新建分区
# p - 主分区
# 选择分区号
# 选择起始扇区
# 选择结束扇区(或 +2G 指定大小)
# t - 修改分区类型
# 82 - Linux swap 类型代码
# w - 保存退出

# 3. 格式化 Swap 分区
mkswap /dev/sdb1

# 4. 启用 Swap
swapon /dev/sdb1

# 5. 验证
swapon --show

4.2 使用 parted 创建 Swap 分区(GPT)

parted /dev/sdb

# parted 交互命令
(parted) mkpart primary linux-swap 0% 2G
(parted) print
(parted) quit

# 格式化
mkswap /dev/sdb1

# 启用
swapon /dev/sdb1

5. swapon 和 swapoff 命令详解

5.1 swapon 命令

# 启用指定的 Swap 文件/分区
swapon /swapfile
swapon /dev/sdb1

# 启用所有 Swap(读取 /etc/fstab 中的 Swap 条目)
swapon -a

# 显示 Swap 信息
swapon --show
swapon -v

# 启用时指定优先级(-1 到 -2,数字越大优先级越高)
swapon -p 10 /swapfile

5.2 swapoff 命令

# 禁用指定的 Swap
swapoff /swapfile
swapoff /dev/sdb1

# 禁用所有 Swap
swapoff -a

# 注意:禁用 Swap 时,Swap 中的数据会移回物理内存
# 如果物理内存不足,可能导致 OOM

5.3 Swap 优先级(Priority)

当有多个 Swap 时,可以通过优先级控制使用顺序:

# 查看当前优先级
swapon --show

# 启用时指定优先级(-1 到 32767,数字越大越优先)
swapon -p 100 /swapfile1
swapon -p 200 /swapfile2

# 优先级相同的 Swap,会轮询使用(提高性能)

6. swappiness 参数调优

6.1 什么是 swappiness

swappiness 是 Linux 内核参数,控制内核将内存页交换到 Swap 的倾向程度。

  • 值范围:0 - 100
  • 默认值:60(大多数发行版)
swappiness 值 含义
0 尽量不使用 Swap(除非内存完全耗尽)
1 - 30 低交换倾向,适合大内存服务器
60 默认值,平衡设置
80 - 100 高交换倾向,适合桌面系统

6.2 查看当前 swappiness

# 查看当前值
cat /proc/sys/vm/swappiness

# 或使用 sysctl
sysctl vm.swappiness

6.3 临时修改 swappiness

# 临时修改(重启后失效)
sysctl vm.swappiness=10

# 或直接写入
echo 10 > /proc/sys/vm/swappiness

6.4 永久修改 swappiness

# 编辑 sysctl 配置文件
vim /etc/sysctl.conf

# 添加或修改以下行
vm.swappiness=10

# 使配置生效
sysctl -p

# 验证
sysctl vm.swappiness

6.5 不同场景的 swappiness 推荐值

场景 推荐值 说明
数据库服务器(MySQL/PostgreSQL) 1 - 10 避免 Swap 影响数据库性能
Web 服务器 10 - 30 适度使用 Swap
桌面系统 60 - 80 平衡响应速度
内存紧张的 VPS 30 - 60 适度交换

7. 配置永久挂载(fstab)

Swap 需要配置到 /etc/fstab 中,实现开机自动启用。

7.1 Swap 文件永久挂载

# 1. 获取 Swap 文件的 UUID(可选,Swap 文件通常直接用路径)
# Swap 文件一般不需要 UUID

# 2. 编辑 /etc/fstab
vim /etc/fstab

# 3. 添加以下行
/swapfile none swap sw 0 0

# 4. 验证配置(不要直接重启!先测试)
# 先禁用当前 Swap
swapoff /swapfile

# 再启用所有 fstab 中的 Swap
swapon -a

# 验证
swapon --show
free -h

7.2 Swap 分区永久挂载

# 1. 获取 Swap 分区的 UUID
blkid /dev/sdb1

# 输出示例:
# /dev/sdb1: UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="swap"

# 2. 编辑 /etc/fstab
vim /etc/fstab

# 3. 添加以下行(推荐使用 UUID)
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 none swap sw 0 0

# 或者直接使用设备路径(不推荐)
/dev/sdb1 none swap sw 0 0

# 4. 验证
swapoff /dev/sdb1
swapon -a
swapon --show

7.3 fstab Swap 条目格式

<device>    <mount_point>    <type>    <options>    <dump>    <pass>

对于 Swap:

  • <device>:Swap 文件路径或 UUID
  • <mount_point>:none(Swap 没有挂载点)
  • <type>:swap
  • <options>:sw(Swap 专用选项)
  • <dump>:0(不备份)
  • <pass>:0(不 fsck 检查)

8. 调整 Swap 大小

8.1 扩大 Swap 文件

# 1. 禁用当前 Swap
swapoff /swapfile

# 2. 删除旧文件
rm /swapfile

# 3. 创建新的更大的 Swap 文件
dd if=/dev/zero of=/swapfile bs=1M count=4096   # 4G
chmod 600 /swapfile
mkswap /swapfile

# 4. 重新启用
swapon /swapfile

# 5. 验证
free -h

8.2 使用 LVM 动态调整(高级)

如果 Swap 在 LVM 上,可以动态调整:

# 查看卷组空间
vgs

# 扩展 Swap 逻辑卷
lvextend -L +2G /dev/vg00/swap

# 重新格式化(需要先禁用)
swapoff /dev/vg00/swap
mkswap /dev/vg00/swap
swapon /dev/vg00/swap

9. Swap 性能监控

9.1 查看 Swap 使用情况

# 使用 vmstat 查看交换活动
vmstat 1 5

# 输出示例:
# procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
#  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
#  1  0      0 1258368  87652 4521368    0    0     2     8   42   68  1  0 99  0  0

# si = swap in(从 Swap 读入内存)
# so = swap out(从内存写出到 Swap)
# 如果 si/so 持续大于 0,说明系统在频繁交换,性能会下降

9.2 使用 sar 监控历史 Swap 活动

# 安装 sysstat
apt install sysstat   # Ubuntu/Debian
yum install sysstat   # CentOS/RHEL

# 查看 Swap 统计
sar -S 1 5

# 查看内存和 Swap 统计
sar -r 1 5

9.3 查看进程 Swap 使用情况

# 查看每个进程的 Swap 使用量
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | head -10

# 或使用 smem 工具
apt install smem
smem -t -k -p

10. 常见问题排查

10.1 Swap 无法启用:权限错误

# 错误:swapon: /swapfile: insecure permissions 0644, 0600 suggested.
# 解决:
chmod 600 /swapfile
swapon /swapfile

10.2 Swap 文件创建失败:磁盘空间不足

# 检查磁盘空间
df -h

# 清理空间或选择其他位置创建 Swap 文件

10.3 系统仍然 OOM,但 Swap 未使用

# 检查 swappiness
sysctl vm.swappiness

# 如果值为 0,适当调大
sysctl vm.swappiness=10

# 检查是否有内存 cgroup 限制
cat /sys/fs/cgroup/memory/memory.limit_in_bytes

10.4 删除 Swap

# 1. 禁用 Swap
swapoff /swapfile

# 2. 从 fstab 中删除对应行
vim /etc/fstab
# 删除或注释掉 Swap 相关行

# 3. 删除 Swap 文件
rm /swapfile

# 4. 验证
free -h
swapon --show

11. Swap 大小建议

11.1 传统建议(Red Hat 建议)

物理内存 推荐 Swap 大小
≤ 2GB 内存的 2 倍
2GB - 8GB 等于内存大小
8GB - 64GB 至少 4GB
> 64GB 至少 4GB(按需)

11.2 现代服务器建议

场景 内存 推荐 Swap
小型 VPS 1GB - 2GB 1GB - 2GB
中型服务器 4GB - 8GB 2GB - 4GB
大型服务器 16GB+ 0GB - 8GB
数据库服务器 任意 尽量小或 0
桌面系统 任意 等于内存或更大

注意:现代服务器内存充足的情况下,可以配置较小的 Swap 或不配置 Swap。但某些应用程序(如 Hibernate)需要 Swap。

12. 总结

本文详细介绍了 Linux Swap 的管理和配置:

  1. Swap 原理:虚拟内存机制,在物理内存不足时提供额外空间
  2. 创建 Swap:Swap 文件(灵活)和 Swap 分区(性能好)
  3. swapon/swapoff:启用和禁用 Swap 的命令
  4. swappiness 调优:控制交换倾向,推荐数据库服务器设为 10 以下
  5. 永久挂载:配置 /etc/fstab 实现开机自动启用
  6. 性能监控:使用 vmstat、sar 监控交换活动

最佳实践:

  • 优先使用 Swap 文件,灵活且易于调整
  • 设置正确的权限(chmod 600)
  • 根据服务器角色调整 swappiness
  • 避免频繁交换(si/so 持续 > 0 说明内存不足)
  • 数据库等性能敏感服务尽量使用物理内存,减少 Swap 使用