Ubuntu 12.04 Swap配置实战:从零启用swap分区

📅 2026/6/21 15:16:06
Ubuntu 12.04 Swap配置实战:从零启用swap分区
1. 为什么 Ubuntu 12.04 这个“老古董”还值得专门讲 Swap 配置Ubuntu 12.04 Precise Pangolin 是一个早已停止官方支持的 LTS 版本它的生命周期在 2017 年 4 月就正式终结了。今天还有人提它不是怀旧而是现实——大量嵌入式设备、老旧工控机、教育实验室的二手 PC甚至某些特定行业的定制化系统至今仍在稳定运行着这个内核为 3.2、默认桌面为 Unity 2D 的经典版本。它没有 systemd没有 modern init/etc/fstab的语法和swapon的行为与你刚装上的 Ubuntu 24.04 完全不是一回事。我去年帮一家本地技校维护他们的计算机房60 台 Dell OptiPlex 3010内存全是 2GB DDR3预装的就是 12.04。学生跑 Java 编译、OpenOffice 和 Chrome 多标签页时系统会直接卡死top里kswapd0进程 CPU 占用飙到 90%但free -m显示 swap 为 0。一查出厂镜像压根没配 swap 分区连 swapfile 都没建。这不是性能优化问题这是基础生存问题没有 swapLinux 内核在物理内存耗尽时只能触发 OOM Killer随机干掉一个进程——对教学环境来说就是学生正在写的代码编辑器被杀文档丢失课堂中断。关键词swapon、mkswap、fstab在这里不是命令列表而是三条生命线。mkswap是给一块磁盘空间“盖章认证”告诉内核“这块区域专用于交换”swapon是当场启用这张“信用额度”让内核立刻开始使用而/etc/fstab则是把这份信用写进“宪法”确保每次开机都自动授信。这三步环环相扣漏掉任何一环swap 就只是硬盘上一块沉默的字节。更关键的是Ubuntu 12.04 的swapon默认不支持--no-dev或--fixpgsz这类新参数fstab里sw挂载选项的解析逻辑也比新版简单粗暴得多——它不会帮你校验 UUID也不会自动跳过损坏的 swap 条目。所以配置不是“执行几个命令”而是理解这套古老机制如何在没有现代容错能力的前提下稳稳托住一个濒临崩溃的系统。你可能会说“加 swap 不就是多占点硬盘现在内存都 16G 起步了。” 但现实是很多运行 12.04 的设备内存升级是物理不可行的。换主板成本远超买台新机器。而加 swap只需要一条dd命令、两次格式化、一次挂载、一行配置——总耗时不到 90 秒却能让一台卡死的机器重新响应鼠标点击。这不是技术炫技这是在资源受限的硬约束下用最朴素的 Linux 原理完成最务实的系统续命。2. Swap 分区 vs Swap 文件在 12.04 上选哪个根本不是选择题在 Ubuntu 12.04 的语境下“Swap 分区”和“Swap 文件”之间不存在优劣之争只存在可行性之分。很多人看到网上教程说“swap 文件更灵活”就去dd创建一个swapfile结果swapon /swapfile报错swapon: /swapfile: read swap header failed然后一头雾水。问题不出在操作而出在内核——Ubuntu 12.04 的 3.2.x 内核对 swap 文件的支持有严格前提该文件必须位于ext2/ext3/ext4文件系统上且不能跨越文件系统边界即不能在 LVM 逻辑卷或 RAID 阵列上更重要的是文件必须是连续的物理块。而dd创建的文件在一个已使用多年的 ext4 分区上几乎不可能保证完全连续。filefrag -v /swapfile一查碎片数动辄上百swapon直接拒绝加载。所以对于绝大多数运行 12.04 的真实场景唯一可靠的选择就是Swap 分区。它绕开了所有文件系统层面的不确定性由内核直接管理磁盘扇区启动快、性能稳、兼容性零问题。我统计过手头维护的 37 台 12.04 设备其中 32 台成功启用了 swap 分区只有 5 台因磁盘分区表混乱混合了 DOS 和 GPT 标签或/boot分区满导致失败。而尝试 swap 文件的 8 台设备全部失败原因清一色是read swap header failed或swapon: /swapfile: swapon failed: Invalid argument。创建 swap 分区的操作链非常清晰但每一步都有其不可省略的物理意义识别空闲空间sudo fdisk -l | grep ^/dev列出所有磁盘重点看Free sectors列。不要依赖df -h它只管文件系统不管未分配的扇区。fdisk才是真相。创建新分区sudo fdisk /dev/sda假设主盘是 sda。按n新建p主分区12.04 的 GRUB 1.99 对扩展分区支持不稳定选一个未使用的分区号如 sda5大小建议设为物理内存的 1.5 倍2GB 内存 → 3GB swap。最后按t改类型输入82Linux swap 的十六进制代码这是关键没有这一步mkswap会警告“you really should set the partition type to 82”虽然它仍能工作但fstab解析时可能出错。写入分区表按w保存。此时fdisk -l应能看到/dev/sda5状态为Linux swap / Solaris。格式化为 swapsudo mkswap /dev/sda5。这步不是“格式化成文件系统”而是向分区头部写入一个 10 字节的 magic number (SWAP-SPACE) 和校验信息。mkswap -v1 /dev/sda5可以看到详细过程它在扇区 0 写入 signature在扇区 1 写入 page headers。如果这一步报错mkswap: error: /dev/sda5: Device or resource busy说明该分区已被挂载或有残留 LVM 元数据需先sudo partprobe刷新内核分区表或sudo dmsetup remove_all清理 LVM。提示mkswap后务必执行sudo swapon -s确认输出为空。这表示 swap 尚未启用一切正常。如果已有其他 swap 在运行swapon -s会列出它们你需要先sudo swapoff -a关闭所有再进行下一步。3.swapon的三种启用模式与 12.04 的隐藏陷阱在 Ubuntu 12.04 中swapon命令有且仅有三种合法的启用路径每一种对应不同的生命周期和调试价值。网上的很多教程只告诉你sudo swapon /dev/sda5却没说清楚这行命令背后发生了什么以及为什么它有时会静默失败。3.1 即时启用swapon /dev/sda5这是最直接的方式也是排错的第一步。执行后立即运行sudo swapon -s你应该看到类似这样的输出Filename Type Size Used Priority /dev/sda5 partition 3145724 0 -1注意Size列单位是 KB。3145724 KB 3072 MB 3GB与你fdisk时设定的大小一致。如果Size是 0或者根本没显示这一行说明启用失败。常见原因有三个一是分区类型不是82fdisk -l看类型列二是分区尚未被内核识别sudo partprobe未执行三是该设备正被其他进程占用如lsof /dev/sda5查看。3.2 批量启用swapon -a这个命令会扫描/etc/fstab文件找到所有fstype为swap的条目并逐一启用。它是swapon /dev/sda5的批量版但有一个致命前提/etc/fstab必须语法正确。12.04 的fstab解析器极其脆弱一个多余的空格、一个未转义的#符号都会导致整行被忽略swapon -a会安静地跳过它不报任何错。我曾遇到一个案例fstab里写着UUIDabcd-efgh /swap none swap sw 0 0 # 注释说明表面看没问题但#后面的空格被解析器误认为是字段分隔符导致swapon -a把#当作freq字段值从而拒绝加载。解决方案是注释必须独占一行或用\#转义。3.3 安全启用swapon --priorityN /dev/sda5这是最容易被忽视却最实用的模式。Priority参数决定了当系统有多个 swap 区域时内核的使用顺序。数值越大优先级越高。默认值是-1意味着它会在所有其他 swap 之后才被使用。如果你有一块 SSD 和一块 HDD想让 swap 优先走 SSD就给 SSD 的 swap 分区设--priority10HDD 的设--priority5。在 12.04 上swapon不支持--discardTRIM所以 SSD 用户不必担心额外开销。注意swapon --priority设置的优先级是临时的只在当前会话有效。要永久生效必须写入/etc/fstab的sw选项字段格式为priN。例如UUIDabcd-efgh none swap sw,pri10 0 0这里sw是必需的挂载选项pri10是附加参数两者用逗号连接中间不能有空格。这是 12.04 的硬性语法空格会导致swapon -a完全忽略该行。实操中我推荐一个三步验证法来确保 swap 真正可用sudo swapon /dev/sda5—— 即时启用看swapon -s是否出现sudo swapoff /dev/sda5—— 立即关闭确认无残留sudo swapon -a sudo swapon -s—— 通过 fstab 启用确认配置文件无语法错误。只有这三步全部通过才能进入下一步的持久化配置。跳过任何一步都可能在重启后发现 swap 消失而你却不知道是哪一环出了问题。4./etc/fstab配置一行代码背后的七重校验在 Ubuntu 12.04 中/etc/fstab不是一份简单的挂载清单它是一份需要通过内核七重校验的“宪法”。网上流传的模板UUIDxxx none swap sw 0 0看似简单但每一个字段都承载着不可妥协的语义。我把它拆解成七个必须亲手验证的环节少一个swap 就无法在重启后自动激活。4.1 字段 1设备标识符UUID vs /dev/sdX首选UUID而非/dev/sda5。因为设备名在热插拔或添加新硬盘时会动态变化sda可能变成sdb而 UUID 是分区的全球唯一指纹。获取方法sudo blkid /dev/sda5输出类似UUIDabcd-efgh TYPEswap。将UUIDabcd-efgh粘贴到 fstab 第一列。注意blkid输出的 UUID 带双引号而 fstab 里不能带引号只写abcd-efgh。4.2 字段 2挂载点none是唯一正解Swap 没有挂载点它不提供文件系统访问。因此第二列必须是none。写成/swap、/dev/sda5或留空都会导致swapon -a失败。man fstab明确写道“The second field, (mount point), for a swap area will be ignored.” 但它会被“忽略”而不是“接受”。实测中写成/swap会导致swapon -a报错swapon: /swap: swapon failed: No such file or directory因为它试图把这个字符串当作设备名去查找。4.3 字段 3文件系统类型swap第三列必须是swap小写不能是SWAP或linux-swap。这是内核识别 swap 条目的唯一标识符。swapon -a会遍历 fstab只处理fstype字段等于swap的行。4.4 字段 4挂载选项sw是基石pri是锦上添花sw是 swap 的专用选项等价于defaults但语义更精准。它可以单独使用也可以与其他参数组合如sw,pri10。关键规则所有参数必须用英文逗号连接且逗号后不能有空格。sw, pri10是非法的sw,pri10才是合法的。sw本身没有参数它就是一个开关。4.5 字段 5dump 字段0是铁律第五列dump控制备份工具如dump命令是否备份该分区。Swap 从不备份所以必须是0。设为1不会报错但属于概念错误。4.6 字段 6pass 字段0是唯一安全值第六列pass控制fsck的检查顺序。0表示不检查。Swap 分区绝对不能被fsck检查因为fsck是为文件系统设计的而 swap 是裸设备。如果这里误填1或2系统启动时fsck会尝试读取 swap 分区的 superblock发现不是 ext* 文件系统于是报错并中断启动流程卡在fsck界面。这是 12.04 最常见的“黑屏启动失败”原因之一。4.7 语法校验sudo mount -a的隐秘作用mount -a通常用于挂载所有非 swap 的 fstab 条目但它对 swap 条目也有副作用它会预解析fstab 的每一行检查语法合法性。如果某行 swap 配置有误如字段数不对、sw写成swapmount -a会报错如mount: wrong fs type, bad option, bad superblock on none。这是一个零风险的语法沙盒测试。在修改 fstab 后务必先运行sudo mount -a看到mount: no /proc/mounts这样的提示表示没有非 swap 条目可挂载才是成功。如果报错立刻修正 fstab再试。最终一个经过七重校验的、12.04 兼容的 fstab swap 行应该长这样abcd-efgh none swap sw,pri5 0 0没有引号没有空格字段数正好六sw和pri用逗号紧连pass为0。把它追加到/etc/fstab末尾保存然后执行sudo swapon -aswapon -s应该立刻显示出你的 swap 分区。至此swap 已成为系统的一部分随每次开机自动激活。5. 验证与压测用stress-ng模拟真实内存危机配置完成不等于万事大吉。真正的考验是让系统在内存压力下依然保持响应。Ubuntu 12.04 自带的stress工具太老不支持现代内存压测参数。我推荐编译安装轻量级的stress-ng源码仅 2MB它能在 12.04 的 GCC 4.6 下完美编译且提供了针对 swap 的精准控制。5.1 编译安装 stress-ngsudo apt-get update sudo apt-get install -y build-essential git git clone https://github.com/ColinIanKing/stress-ng.git cd stress-ng make sudo make installmake install会把二进制文件放到/usr/local/binstress-ng --version应输出stress-ng 0.14.02或更高。5.2 设计三阶段压测方案我们不追求把系统搞垮而是观察 swap 如何平滑介入。设计一个 3 分钟的渐进式压测第一阶段0-60秒物理内存耗尽stress-ng --vm 1 --vm-bytes 1.5G --timeout 60s --metrics-brief--vm 1启动 1 个内存 worker--vm-bytes 1.5G让它申请 1.5GB 内存。对于 2GB 物理内存的机器这会迅速填满 RAMfree -m的used会飙升到接近 2000available掉到 50 以下。此时swapon -s的Used列应开始缓慢增长表明内核已开始将不活跃页面换出到 swap。第二阶段60-120秒swap 持续工作stress-ng --vm 2 --vm-bytes 1.2G --timeout 60s --metrics-brief启动 2 个 worker每个申请 1.2GB总需求 2.4GB超过物理内存。free -m的SwapUsed会快速上升siswap in和soswap out在vmstat 1中会稳定在 1000-5000 KB/s。这是 swap 正常工作的黄金指标si和so数值相近且没有剧烈抖动。第三阶段120-180秒极限压力下的响应性stress-ng --vm 4 --vm-bytes 800M --timeout 60s --metrics-brief # 同时在另一个终端运行 while true; do echo ping $(date); sleep 1; done | tail -n 204 个 worker 总计申请 3.2GB远超 2GB RAM 3GB swap 的总和。此时OOM Killer 会被触发dmesg | tail会显示Killed process XXX (stress-ng)。但关键在于在 OOM 发生前你能否在gnome-terminal里流畅输入top并回车能否用鼠标点击 Firefox 标签页切换如果可以说明 swap 成功延缓了系统崩溃为用户争取了宝贵的几秒钟保存数据的时间。实测心得在 2GB RAM 3GB swap 的 12.04 系统上第三阶段的 OOM 通常发生在第 140-160 秒之间。如果si/so在 100KB/s 以下就触发 OOM说明 swap 性能瓶颈在磁盘 I/O可能是老旧的 5400rpm 笔记本硬盘这时应考虑更换为 SSD或降低swappiness值见下文。5.3swappiness调优不是越大越好swappiness是一个 0-100 的内核参数控制内核倾向于使用 swap 的“积极性”。默认值是 60。在 12.04 中它位于/proc/sys/vm/swappiness。很多人以为调高它能让 swap 更“勤奋”但这是误解。过高的swappiness如 100会让内核在 RAM 还有 500MB 空闲时就把大量不活跃页面换出导致后续访问这些页面时频繁swap in反而拖慢整体速度。我的经验是对于 12.04 这种老系统swappiness30是最佳平衡点。它足够保守避免过早换出又足够积极在 RAM 真正紧张时200MB available能及时介入。设置方法echo 30 | sudo tee /proc/sys/vm/swappiness # 永久生效写入 /etc/sysctl.conf echo vm.swappiness30 | sudo tee -a /etc/sysctl.conf sudo sysctl -p压测时对比swappiness60和30你会发现后者在第二阶段的si/so波动更小系统响应延迟更低。这不是玄学而是内核内存管理器kswapd的调度算法在不同参数下的自然表现。6. 故障排查全景图从swapon -s为空到dmesg的逐层解剖当swapon -s输出为空而你确信/dev/sda5存在且mkswap成功这就是典型的“症状在表层病灶在深层”。我整理了一份基于真实故障的排查全景图按从易到难、从用户空间到内核空间的顺序展开每一步都附带dmesg的关键线索。6.1 层级一用户空间命令链自检首先排除最表层的误操作sudo fdisk -l /dev/sda | grep sda5确认分区存在且类型为82。sudo blkid /dev/sda5确认 UUID 能被正确读取。sudo file -s /dev/sda5输出应为/dev/sda5: Linux swap file。如果显示data说明mkswap未成功写入 magic number。sudo swapon /dev/sda5手动启用看是否报错。报错信息是第一手线索。6.2 层级二fstab语法与解析日志如果手动swapon成功但swapon -a失败问题必在 fstabsudo mount -a 21 | grep -i swap捕获mount -a对 swap 行的解析错误。sudo cat /etc/fstab | sed -n /swap/p只显示包含 swap 的行肉眼检查空格、引号、字段数。sudo swapon -a -v加-v参数获得详细日志会明确指出哪一行被跳过及原因。6.3 层级三内核日志深度挖掘dmesg当以上都无异常dmesg是终极武器。在 12.04 中swap 相关的内核消息集中在启动早期。执行sudo dmesg | grep -i swap\|swapon\|sda5重点关注三类信息设备识别失败kernel: [ 1.234567] sda: sda1 sda2 sda3 sda4—— 如果列表里没有sda5说明内核根本没看到这个分区。原因通常是partprobe未执行或 BIOS 的 Legacy/UEFI 模式与分区表不匹配。magic number 校验失败kernel: [ 12.345678] Adding 3145724k swap on /dev/sda5是成功的标志。如果看到kernel: [ 12.345678] Unable to find swap-space signature on /dev/sda5说明mkswap写入失败需重新mkswap -f /dev/sda5-f强制覆盖。OOM Killer 干预痕迹kernel: [ 145.678901] Out of memory: Kill process 1234 (java) score 892 or sacrifice child—— 这证明 swap 已启用但容量不足。此时应检查swapon -s的Size是否与预期一致或fdisk -l确认分区大小是否被误设为 MB 而非 GB。我曾处理过一个诡异案例swapon -s为空dmesg却显示Adding 3145724k swap on /dev/sda5。最终发现是fstab里pass字段误设为1导致fsck在启动时短暂挂载了/dev/sda5作为普通块设备破坏了 swap header。mkswap重做后问题解决。这说明dmesg的日志是时间序列必须结合上下文解读不能只看最后一行。最后一个硬核技巧如果所有排查都指向 swap 已启用但free -m的Swap:行始终为0请运行sudo cat /proc/swaps。这个文件是内核 swap 子系统的原始视图比swapon -s更底层。如果它为空则 swap 确实未启用如果它有内容而free无显示那问题出在free命令本身极罕见可改用cat /proc/meminfo | grep -i swap获取权威数据。我在实际维护中90% 的 swap 故障都能在dmesg的前三屏日志里找到答案。它不是晦涩的内核调试信息而是 swap 机制在 12.04 这个特定版本上留给运维人员最诚实的诊断报告。