Linux如何建立交换分区(Swap分区)?

当你在Linux系统中运行大型程序(如视频编辑、虚拟机)或多任务处理时,是否遇到过“内存不足”的错误?这通常是因为物理内存(RAM)被耗尽,而系统没有足够的**交换空间(Swap Space)**来缓解压力。Swap分区作为Linux系统的“虚拟内存扩展”,能将不活跃的内存页临时存储到磁盘,避免程序崩溃或被OOM Killer(内存溢出杀手)强制终止。

本文将详细讲解Swap分区的原理、创建步骤、最佳实践与排障方法,即使是Linux新手也能一步步跟着操作。我们会重点覆盖专用Swap分区(而非Swap文件)的创建,因为它更稳定、性能更可预期。

目录#

  1. 什么是Swap分区?
  2. Swap分区的作用与原理
  3. 创建Swap分区的前提条件
  4. 步骤1:检查当前Swap状态
  5. 步骤2:选择磁盘或空闲分区
  6. 步骤3:创建Swap分区(新分区/现有分区)
  7. 步骤4:格式化Swap分区
  8. 步骤5:启用Swap分区
  9. 步骤6:设置开机自动挂载
  10. Swap分区的最佳实践
  11. 常见问题与排查
  12. 总结
  13. 参考资料

1. 什么是Swap分区?#

Swap分区是磁盘上的专用分区,用于存储Linux系统的虚拟内存。它与Swap文件的核心区别在于:

  • Swap分区:是磁盘上的独立分区,直接由内核管理,性能更稳定(无需经过文件系统层)。
  • Swap文件:是文件系统中的普通文件(如/swapfile),灵活但性能略低(适合临时扩展交换空间)。

本文聚焦Swap分区,因为它是传统且更可靠的方案,适合需要长期稳定交换空间的场景(如服务器、桌面系统)。

2. Swap分区的作用与原理#

核心作用#

当物理内存(RAM)不足时,内核会将不活跃的内存页(比如后台程序的数据)从RAM“换出”(Page Out)到Swap分区,释放RAM给更需要的程序。当程序需要这些页时,再从Swap“换入”(Page In)回RAM。

关键概念#

  • OOM Killer:如果没有Swap空间,当RAM耗尽时,内核会强制终止占用内存最多的进程(比如你的Chrome浏览器),避免系统崩溃。
  • Swappiness:内核使用Swap的积极性(取值0-100),默认值为60。值越低,内核越倾向于使用RAM而非Swap(适合SSD);值越高,越积极使用Swap(适合HDD)。

3. 创建Swap分区的前提条件#

在开始操作前,请确保满足以下条件:

  1. Root权限:需要sudo或直接登录root用户(所有磁盘操作都需要高权限)。
  2. 未分配磁盘空间:磁盘上有未使用的空间(或空闲分区),可以通过lsblkfdisk -l查看。
  3. 数据备份:所有磁盘操作都有风险,请备份重要数据(避免误删分区)。
  4. 基础工具:系统已安装fdisk(MBR磁盘)或gdisk(GPT磁盘)、mkswapswapon等工具(大部分Linux发行版默认预装)。

4. 步骤1:检查当前Swap状态#

首先,我们需要确认系统当前的Swap使用情况,避免重复创建或误操作。

常用命令#

  1. 查看活跃Swap

    swapon --show

    示例输出(表示当前有一个Swap分区/dev/sda3,大小8GB,未使用):

    NAME      TYPE      SIZE USED PRIO
    /dev/sda3 partition 8G   0B   -2
    
  2. 查看内存与Swap总览(人类可读格式):

    free -h

    示例输出:

    total        used        free      shared  buff/cache   available
    Mem:           15Gi       2.3Gi       10Gi       152Mi       2.4Gi       12Gi
    Swap:          8Gi         0B        8Gi
    
  3. 通过Proc文件系统查看

    cat /proc/swaps

    输出与swapon --show类似,但更详细。

5. 步骤2:选择磁盘或空闲分区#

接下来,我们需要找到可以用来创建Swap分区的未分配空间空闲分区

查看磁盘布局#

使用lsblk(推荐,更直观)或fdisk -l列出所有磁盘:

lsblk

示例输出:

NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda           8:0    0   40G  0 disk 
├─sda1        8:1    0  512M  0 part /boot/efi
├─sda2        8:2    0    1G  0 part /boot
└─sda3        8:3    0   10G  0 part /
sdb           8:16   0   20G  0 disk  # 未分区的磁盘(大小20GB)
nvme0n1     259:0    0  512G  0 disk 
├─nvme0n1p1 259:1    0  512M  0 part /boot/efi
└─nvme0n1p2 259:2    0  511G  0 part /home

关键判断标准#

  • 未分配空间TYPE=disk的设备(如sdb),且没有子分区(sdb下没有sdb1),表示该磁盘完全未使用。
  • 空闲分区TYPE=part的设备(如sda4),且MOUNTPOINTS为空(未挂载),表示该分区未被使用。

⚠️ 警告不要使用已挂载的分区(如/dev/sda3,它挂载到/),否则会导致数据丢失!

6. 步骤3:创建Swap分区#

根据磁盘的未分配空间类型,分为两种情况:从无到有创建新分区,或复用现有空闲分区。

前置知识:MBR vs GPT#

  • MBR:传统分区格式,支持最多4个主分区(或3个主分区+1个扩展分区),单分区最大2TB。
  • GPT:现代分区格式,支持无限分区(取决于操作系统),单分区最大18EB,支持UEFI启动。

选择工具:

  • MBR磁盘:使用fdisk
  • GPT磁盘:使用gdisk(或fdisk -g,但gdisk更可靠)。

情况1:从无到有创建新分区(以MBR磁盘为例)#

假设我们要在未分区的sdb磁盘(20GB)上创建一个10GB的Swap分区。

步骤1:进入fdisk工具#

sudo fdisk /dev/sdb

进入交互模式后,会显示如下提示:

Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

步骤2:创建新分区#

输入以下命令(按顺序执行):

  1. p:查看当前分区表(确认sdb未分区)。
  2. n:创建新分区。
  3. 选择分区类型:输入p(主分区,MBR最多4个)。
  4. 分区号:默认1(直接按Enter)。
  5. 起始扇区:默认2048(直接按Enter)。
  6. 结束扇区:输入+10G(表示创建10GB的分区,或直接按Enter用满剩余空间)。
  7. t:修改分区类型(默认是Linux,需要改为Linux swap)。
  8. 输入分区号:1(刚创建的sdb1)。
  9. 输入分区类型代码:82(MBR的Swap类型代码)。
  10. p:再次查看分区表,确认类型为Linux swap
  11. w:保存并退出(此操作会修改磁盘分区表,不可逆!)。

完整交互示例#

Command (m for help): p
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: Virtual Disk    
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x12345678

# 此时sdb未分区,所以没有设备列表

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-41943039, default 2048): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-41943039, default 41943039): +10G

Created a new partition 1 of type 'Linux' and of size 10 GiB.

Command (m for help): t
Selected partition 1
Hex code or alias (type L to list all): 82
Changed type of partition 'Linux' to 'Linux swap'.

Command (m for help): p
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: Virtual Disk    
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x12345678

Device     Boot Start      End  Sectors Size Id Type
/dev/sdb1        2048 20973567 20971520  10G 82 Linux swap

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

情况2:复用现有空闲分区#

如果已有未挂载的空闲分区(如/dev/sda4),可以直接修改其类型为Swap(注意:此操作会清空分区所有数据!)。

步骤1:卸载分区(如果已挂载)#

sudo umount /dev/sda4

步骤2:修改分区类型#

使用fdisk进入分区工具,执行t命令,将分区类型改为82(MBR)或8200(GPT),最后w保存。

7. 步骤4:格式化Swap分区#

创建好Swap分区后,需要用mkswap工具初始化分区(类似mkfs格式化文件系统)。

命令示例#

假设新分区是/dev/sdb1

sudo mkswap /dev/sdb1

输出说明#

Setting up swapspace version 1, size = 10 GiB (10736762880 bytes)
no label, UUID=12345678-1234-1234-1234-123456789abc
  • size:分区大小(10GB)。
  • UUID:分区的唯一标识符(后续会用到,比/dev/sdb1更可靠)。

8. 步骤5:启用Swap分区#

使用swapon命令启用刚创建的Swap分区:

sudo swapon /dev/sdb1

验证启用结果#

再次运行swapon --show,如果看到新的Swap分区,表示启用成功:

NAME      TYPE      SIZE USED PRIO
/dev/sda3 partition 8G   0B   -2
/dev/sdb1 partition 10G  0B   -3

9. 步骤6:设置开机自动挂载#

默认情况下,重启后Swap分区不会自动启用,需要将其添加到/etc/fstab文件(系统开机挂载配置文件)。

步骤1:获取分区UUID#

使用blkid命令获取Swap分区的UUID(推荐用UUID,避免/dev路径变化):

sudo blkid /dev/sdb1

输出示例:

/dev/sdb1: UUID="12345678-1234-1234-1234-123456789abc" TYPE="swap" PARTUUID="12345678-01"

步骤2:编辑/etc/fstab#

使用文本编辑器(如nanovim)打开/etc/fstab

sudo nano /etc/fstab

步骤3:添加Swap挂载条目#

在文件末尾添加一行(替换为你的UUID):

UUID=12345678-1234-1234-1234-123456789abc none swap defaults 0 0

字段说明#

字段含义
UUID=...Swap分区的唯一标识符(避免/dev路径变化)
noneSwap分区没有挂载点(内核直接管理)
swap文件系统类型(固定为swap
defaults默认挂载选项(包含rwauto等,适合大多数场景)
0dump选项(0表示不备份该分区)
0pass选项(0表示开机不检查该分区(Swap不需要fsck))

步骤4:验证配置#

运行以下命令,测试/etc/fstab是否正确(无输出表示正常):

sudo mount -a

步骤5:重启验证#

重启系统后,运行swapon --show,确认Swap分区自动启用。

10. Swap分区的最佳实践#

1. 大小建议#

Swap大小没有绝对标准,需根据RAM大小工作负载调整:

  • <8GB RAM:Swap大小=1-2倍RAM(如4GB RAM → 4-8GB Swap)。
  • 8-64GB RAM:Swap大小=0.5-1倍RAM(如16GB RAM → 8-16GB Swap)。
  • >64GB RAM:Swap大小=2-4GB(足够应对突发情况)。
  • 冬眠(Hibernation):Swap大小≥RAM(需要将RAM全部数据写入Swap)。

2. SSD vs HDD#

  • SSD:速度快,但有写入寿命限制。建议:
    • 减少Swap使用(设置swappiness=10)。
    • 启用TRIM(在fstab中添加discard选项:defaults,discard)。
  • HDD:速度慢,但写入寿命长。建议:
    • 适当增加Swap大小(如1.5倍RAM)。
    • 设置swappiness=60(默认值,更积极使用Swap)。

3. 优先级设置#

如果有多个Swap分区,可以通过pri选项设置优先级(值越高,越先被使用):

  • 临时设置:sudo swapon -p 10 /dev/sdb1(优先级10)。
  • 永久设置:在/etc/fstab中添加pri=10
    UUID=... none swap defaults,pri=10 0 0
    

4. 避免Swap Thrashing#

如果系统频繁换入换出(Swap Thrashing),会导致性能急剧下降。解决方法:

  • 增加物理内存(最有效的方式)。
  • 减少Swap使用(降低swappiness)。
  • 关闭不必要的后台程序。

11. 常见问题与排查#

1. swapon: invalid argument#

原因:分区类型不是Swap(未执行t命令修改类型),或未执行mkswap
解决:重新修改分区类型,或运行mkswap /dev/sdb1

2. swapon: device or resource busy#

原因:分区已挂载或已启用Swap。
解决:卸载分区(sudo umount /dev/sdb1)或关闭Swap(sudo swapoff /dev/sdb1)。

3. 重启后Swap未自动启用#

原因/etc/fstab中的UUID错误,或语法错误。
解决

  • 重新获取UUID(blkid /dev/sdb1)。
  • 检查/etc/fstab的语法(如空格是否正确)。
  • 运行sudo mount -a测试配置。

4. mkswap: device is busy#

原因:分区正在被使用(如挂载或启用Swap)。
解决:卸载分区或关闭Swap(sudo swapoff /dev/sdb1)。

12. 总结#

创建Swap分区的核心步骤可以总结为:

  1. 检查当前状态swapon --showfree -h
  2. 选择磁盘lsblk找到未分配空间或空闲分区。
  3. 创建分区fdisk/gdisk创建并修改类型为Swap。
  4. 格式化mkswap初始化分区。
  5. 启用swapon启用Swap。
  6. 自动挂载:添加到/etc/fstab

⚠️ 最后提醒:所有磁盘操作都有风险,请务必备份数据!如果不确定,建议先在虚拟机中练习。

13. 参考资料#

  1. Linux Man Pagesman swaponman mkswapman fdiskman gdisk
  2. Red Hat DocumentationSwap Space Recommendations
  3. Ubuntu Community WikiSwapFaq
  4. Kernel Documentationvm.swappiness

希望这篇文章能帮助你顺利创建Swap分区,让Linux系统更稳定!如果有问题,欢迎在评论区交流。