存储实操手册 · 分区 / LVM / swap / 挂载 全流程

把做过的四条线串成可重复的一套:裸分区直挂、LVM 新建再挂、LVM 扩容(含根分区)、swap 启用。每一步都写了「成功长什么样」,勾选框会记住进度。

0 · 环境基线与三条路线的区别 先搞清楚要重复的是哪一条

实验机 manage(Rocky 9,192.168.30.22),三块盘:sda 装系统、sdb 8GiB 空盘、sdc 8GiB 空盘。所有容量以 MiB 为基准(8GiB 盘 = 8192MiB)。

路线设备长什么样能改大小吗fstab 里写什么用在哪
A 裸分区直挂/dev/sdb1不能(要重新分区,等于丢数据)UUID=... 最稳固定大小、简单场景
B LVM 新建/dev/mapper/test-vo能,在线扩/dev/mapper/test-vo 或 UUID要能调整大小的场景
C LVM 扩根/dev/mapper/rlm-root能,在线扩不用改/ 满了
磁盘 sdc→ 分区 sdc1→ PV→ VG test→ LV vo→ XFS→ /vo + fstab

一句话记法:分区是给内核划地段,LVM 是在地段上记账(PV 记容量、VG 记格子、LV 借格子),文件系统是往格子里画书架,挂载是把书架接到目录树上。越靠左边越难改,越靠右边越容易改。

1 · 重置到起点 不重置,第二次做必然撞「已存在」

有两条路。做过实验 C(扩根)之后,只能走 A,因为 XFS 不支持缩小,扩出去的根回不来。

关机操作
# 虚拟机关机后,在 VMware 里恢复到「两块盘已加、尚未分区」的快照
# 我们打过:baseline / baseline-2disks / storage-baseline
成功长什么样:开机后 lsblk 里 sdb、sdc 没有任何分区;vgs 只有 rlm 一个卷组;df -h 里没有 /vo 和 /mnt/data;df -h / 回到 6.2G。

为什么推荐:根分区扩容在文件系统层是不可逆的,手动拆只会在 rlm 里留下一堆碎片空间,永远回不到「干净 7G 卷组」。快照是唯一的「撤销」。

顺序不能乱
# ① 先删 fstab 里的两行(/vo 和 /mnt/data),否则下次开机会卡在 emergency mode
vim /etc/fstab

# ② 卸挂载
umount /vo
umount /mnt/data

# ③ 由内向外拆:LV → VG → PV(和建的时候完全相反)
lvremove -y /dev/test/vo
vgremove test
pvremove /dev/sdc1

# ④ 抹掉残留签名,再删分区
wipefs -a /dev/sdc1 /dev/sdb1
parted /dev/sdc rm 1
parted /dev/sdb rm 1

# ⑤ 让内核重读
partprobe
lsblk -f
成功长什么样:lsblk -f 里 sdb、sdc 下面没有任何子项,FSTYPE 列为空;pvs、vgs 里看不到 test;parted /dev/sdc print 显示无分区。
顺序为什么不能反:LV 里有文件系统,VG 里有 LV,PV 属于 VG。删外层前内层还在用,就会报 device is busy 或 Logical volume ... in use。建的时候由外向内,拆的时候由内向外。
忘了删 fstab 的后果:下次开机 systemd 找不到 /vo 的设备,会掉进 emergency mode,要输 root 密码再用 mount -o remount,rw / 修。这就是为什么改 fstab 一定要紧跟一次 mount -a 验证。

2 · 实验 A:裸分区 → mkfs → 持久挂载 sdb 8GiB → sdb1 1GiB → /mnt/data

目标:建一个 1GiB 的 XFS 分区,开机自动挂到 /mnt/data。这条线不碰 LVM,是最短路径。

lsblk
lsblk -f /dev/sdb
parted /dev/sdb print
成功长什么样:sdb 下面没有 sdb1,FSTYPE 列为空;parted 要么显示 unrecognised disk label(还没分区表),要么显示 gpt 但没有分区行。先确认是空的,再往下走。
为什么必须先看:mklabel 会直接覆盖并清空整块盘的分区表,不问你。这是这条线上唯一一个「一条命令毁全盘」的动作。
parted
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary xfs 1MiB 1025MiB
parted /dev/sdb unit mib print free
成功长什么样:最后一条显示 1 1.00MiB 1025MiB 1024MiB ... primary。起点是 1MiB 而不是 0。

为什么从 1MiB 起:GPT 磁盘开头 0–1MiB 放主分区表和头部,让出来既安全又天然满足 1MiB 对齐(对 SSD、4Kn 盘都友好)。
为什么结束写 1025 而大小是 1024:Start/End 是「坐标」,Size 是差值。1→1025 就是 1024MiB,和你写 1024MiB 的直觉差 1,因为 offset 不是 0。
gpt 还是 msdos:超过 2TiB 必须 gpt;RHEL 9 一律建议 gpt。msdos 的 2T 上限说的是整盘容量,不是单个分区。

partprobe
partprobe /dev/sdb
lsblk /dev/sdb
成功长什么样:lsblk 里出现 sdb1,大小 1G。partprobe 本身无输出。

为什么要这一步:parted 改的是磁盘上的分区表,内核里的分区视图是另一份。不同步就会出现 /dev/sdb1: No such file or directory。新版 udev 大多会自动同步,但考试环境不保证,养成习惯比赌它自动强。

mkfs.xfs
mkfs.xfs /dev/sdb1
成功长什么样:输出末尾 data = ... blocks=262144(262144 × 4K = 1024MiB),没有 error 行。
三种常见拦路话:
· appears to contain an existing filesystem → 上面真有东西,确认要覆盖再加 -f。
· Filesystem should be larger than 300MB → 只是推荐值警告,回车继续即可,不是失败。
· is apparently in use by the system → 分区已被挂载,先 umount。

mkfs 只认设备,不认挂载点。写 mkfs.xfs /mnt/data 会作用到根文件系统上(因为它也是设备上的目录 → 实际会报错但很危险)。永远写 /dev/...。

blkid
blkid /dev/sdb1
成功长什么样:一行 /dev/sdb1: UUID="xxxx-..." BLOCK_SIZE="512" TYPE="xfs"。必须看到 TYPE="xfs"。
blkid 有输出 ≠ 有文件系统:分区表、swap、LVM PV 也都有签名,它能打出东西。判断文件系统只看 TYPE= 那一项,别看到输出就以为 A4 成了。
持久化的唯一位置
mkdir -p /mnt/data
vi /etc/fstab
# 在末尾追加一行(UUID 换成 A5 的真实值):
# UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  /mnt/data  xfs  defaults  0 0

cat /etc/fstab
成功长什么样:cat 打出来的一行里,UUID 与 A5 完全一致、挂载点没拼错、字段之间有空格(tab 也行)。写完一定回读一遍。
六个字段,一个一个对
#字段这里写含义
1设备UUID=...也可以是 /dev/sdb1 或 /dev/mapper/test-vo。UUID 不会因为换槽位、加盘而变,所以最稳
2挂载点/mnt/data目录必须先存在,否则 mount 报 mount point does not exist
3类型xfs写错会报 wrong fs type(也可能是根本没 mkfs)
4选项defaults= rw,suid,dev,exec,auto,nouser,async
5dump0早就不用了,恒 0
6fsck 顺序0XFS 不参与 fsck,恒 0;ext4 的根分区才写 1、其它写 2
写 UUID 还是写设备名?数据盘用 UUID 最稳(换盘序、加硬盘都不受影响);LVM 逻辑卷写 /dev/mapper/vg-lv 也行,因为 LVM 元数据保证名字稳定。绝对不要写 /dev/dm-2 这种,编号每次开机都可能变。
mount -a
systemctl daemon-reload
mount -a
成功长什么样:两条命令都什么都不打印。mount 的哲学是沉默即成功,有输出就是有错。

为什么用 mount -a 而不是 mount /mnt/data:mount -a 按 fstab 全量走一遍,能一次性验出所有条目的问题;mount /mnt/data 也会读 fstab,但只验一条。改完 fstab 一定要 mount -a,否则错误要等到重启才爆,而重启时爆就是 emergency mode。

缺一步都不算过
findmnt /mnt/data
df -hT /mnt/data
mount | grep data
touch /mnt/data/probe && ls -l /mnt/data/probe
成功长什么样:
· findmnt 一行,SOURCE 显示 UUID=...(它显示的是 fstab 里写的原文),FSTYPE xfs,OPTIONS 里有 rw。
· df -hT 的 Size 约 1014M(比 1024M 小,正常,见下方)。
· mount 里能看到 /dev/sdb1 on /mnt/data type xfs。
· 能建出文件 → 真能写。
为什么 df 是 1014M 而不是 1024M:XFS 自己留了内部日志、超级块、inode 元数据。分区 1024MiB 是「地段」,文件系统能用的比它小一点点。记住方向:df ≤ 分区大小,永远如此。
唯一真正的持久化证据
systemctl reboot
# 回来后
df -hT /mnt/data
成功长什么样:重启后没有任何手工操作,/mnt/data 自己就挂好了,Size 还是 1014M。
不重启就等于没验。mount -a 成功只证明「现在能挂」,证明「开机自动挂」的只有重启。考试里这条不能省——评分是在你重启之后做的。

3 · 实验 B:LVM 新建再挂载 sdc1 4GiB → PV → VG test → LV vo → /vo

目标:在 sdc 上建一套 LVM,逻辑卷先 200MiB,挂到 /vo,然后在线扩到 300MiB。这条线比 A 多三个概念,但每一步都只是「记账」。

/dev/sdc1→ pvcreate → PV→ vgcreate → VG test→ lvcreate → LV vo→ mkfs → XFS→ fstab → /vo
parted
parted /dev/sdc mklabel gpt
parted /dev/sdc mkpart primary 1MiB 4097MiB
parted /dev/sdc set 1 lvm on
parted /dev/sdc unit mib print free
partprobe /dev/sdc
成功长什么样:1 1.00MiB 4097MiB 4096MiB primary lvm,Flags 列有 lvm;lsblk 出现 sdc1。

lvm 标记到底干什么用:它只是分区表里的一个类型字节,让 fdisk/parted/blkid 知道「这块别乱动,是 LVM 的地盘」。pvcreate 本身并不检查它——你可以不打标记照样建 PV。但规范做法要打,考试也要求,而且能防止别的工具误认。

pvcreate
pvcreate /dev/sdc1
pvs
pvdisplay /dev/sdc1
成功长什么样:Physical volume "/dev/sdc1" successfully created.;pvs 里一行,PSize 4.00g、PFree 4.00g、VG 列为空(还没入组)。

PV 是什么:在你分区的最前面写一小段 LVM 元数据(PV label),声明「这块地从这里到那里,共多少字节,归 LVM 管」。它不搬数据、不格式化,纯粹是登记。

vgcreate
vgcreate test /dev/sdc1
vgs
vgdisplay test
成功长什么样:Volume group "test" successfully created;vgs 里 test 1 0 0 wz--n- <4.00g <4.00g;vgdisplay 里 PE Size 4.00 MiB、Total PE 1023、Free PE 1023。
为什么 4096MiB 的 PV 只有 1023 个 PE 而不是 1024:PV 头部元数据先占了不到 1MiB,剩下的才切成 4MiB 的格子,除不尽的那点零头丢掉。所以 1023 × 4MiB = 4092MiB,比 4.00g 略小,vgs 显示成 <4.00g。

那个 < 是什么意思:显示值经过四舍五入后比真实值略大,用 < 提醒你「实际比这个数小一点」。反过来如果看到没有 <,就是四舍五入后偏小。看到 < 不用慌,它不是「小于」的意思,是「约等于但别超」。

lvcreate
lvcreate -n vo -L 200MiB test
lvs
lvdisplay /dev/test/vo
成功长什么样:Logical volume "vo" created.;lvs 里 vo test -wi-a----- 200.00m;LV Path 是 /dev/test/vo,同时也存在 /dev/mapper/test-vo(同一个东西两个名字)。
-L 和 -l 不是一回事(最容易搞混的一对):
· -L 200MiB 单位是容量,也可以是 -L 1G、-L +100MiB(带 + 是增量)。
· -l 50 单位是格子数(PE),50 × 4MiB = 200MiB。-l 50%FREE、-l +100%FREE 也是这个参数。
LV 大小必定是 PE 的整数倍,写 -L 201MiB 它会给 204MiB(向上取到整格)。

Attr 那串 -wi-a----- 拆开看:- 普通卷 | w 可写 | i 分配策略继承 | a 已激活 | 后面空位依次是「固定次设备号 / 打开状态 / 目标类型」。挂载之后第 6 位会变成 o(open),就成了你之前看到的 -wi-ao----。

mkfs.xfs
mkfs.xfs /dev/test/vo
成功长什么样:meta-data=/dev/test/vo 开头,data = ... blocks=51200(51200 × 4K = 200MiB),无 error。
200MiB 会触发 Filesystem should be larger than 300MB 警告——这只是推荐值提示(小于 300MB 的 XFS 性能不好),不是失败,回车继续,文件系统照建。你之前看到的 300MiB 就是从这里来的。但真要考 300MiB 的题,就必须写 300 而不是 200。
持久化
mkdir -p /vo
vi /etc/fstab
# 追加:
# /dev/mapper/test-vo  /vo  xfs  defaults  0 0

cat /etc/fstab
systemctl daemon-reload
mount -a
成功长什么样:mount -a 无输出;findmnt /vo 显示 SOURCE /dev/mapper/test-vo、FSTYPE xfs;df -h /vo Size 约 195M(200MiB 减掉 XFS 元数据)。
为什么这里可以写 /dev/mapper/test-vo 而不写 UUID:LVM 的名字由元数据背书,只要 LV 还在,这个名字就不变,而且可读性更好。但 LV 被删了重建,UUID 会变、名字却不变——所以写 mapper 的代价是「数据重建后可能挂错东西」。两种写法考试都接受,写 UUID 更保险。
lvextend
lvextend -L 300MiB /dev/test/vo
lvs
df -h /vo
成功长什么样:Size of logical volume test/vo changed from 200.00 MiB (50 extents) to 300.00 MiB (75 extents). + successfully resized。但此时 df -h /vo 仍然是 195M —— 这是正确的,不是失败。
最容易自我怀疑的一步:lvextend 只改 LV 的账本(说这个卷现在有 75 个格子),文件系统还不知道自己可以变大了。所以 df 不动是必然的。这一步过了、df 没变,说明你理解对了。

-L 300MiB 和 -L +100MiB 的区别:前者是「最终大小」,后者是「再加多少」。题干说「增加到 300MiB」用 -L 300MiB,说「增加 100MiB」用 -L +100MiB。看错一个符号就是错题。

xfs_growfs
xfs_growfs /vo
df -h /vo
成功长什么样:data blocks changed from 51200 to 76800(76800 × 4K = 300MiB);df -h /vo Size 变成 295M。
为什么必须两步:LVM 和文件系统是两层独立记账。LVM 扩容 = 房间变大了;xfs_growfs = 告诉文件系统「你可以去用新空间了」。XFS 只能扩不能缩(ext4 可以缩,用 resize2fs,而且要卸载后缩)。
一步法:lvextend -r -L 300MiB /dev/test/vo。-r = 自动调用对应的文件系统扩容工具(XFS 或 ext4 都认)。但考试和排错都要求你懂两步,因为 -r 需要文件系统已挂载且工具在位,手工两步永远能用。
最后一道
findmnt /vo
df -hT /vo
lvs
systemctl reboot
# 回来后
df -hT /vo ; vgs ; lvs
成功长什么样:重启后 /vo 自动挂载、295M;lvs 里 vo 仍是 300.00m;test 卷组 VFree 从 3.80g 变成 3.70g 左右。

4 · 实验 C:给根分区扩容 sdc2 → vgextend rlm → lvextend root → xfs_growfs /

目标:把 sdc 剩下一半空间做成新 PV,加进系统卷组 rlm,把 / 从 6.2G 扩到约 10.2G。这是唯一一条不可逆的操作,动手前必须打快照。

不可跳过
# 关机 → VMware 里建快照,命名如 before-root-grow → 开机
成功长什么样:快照列表里能看到它,且能正常开机。
为什么这条比前面所有步骤都重要:XFS 不能缩小,lvextend / 之后的根分区没有手工回退方案。方案本身风险低(只是借新盘的空间),但「不可逆」三个字值得一个快照。
parted
parted /dev/sdc unit mib print free
parted /dev/sdc mkpart primary 4097MiB 8191MiB
parted /dev/sdc set 2 lvm on
parted /dev/sdc unit mib print free
成功长什么样:2 4097MiB 8191MiB 4094MiB primary lvm,尾部只剩 0.98MiB Free(那是 GPT 留的,正常)。
三种写法的结局:
· ... 4097MiB 100% → Error: ... sectors 8390656..16777215 / closest ...16777182(占不住磁盘最后一个扇区)
· ... 4097MiB 8192MiB → Error: The location 8192mib is outside of the device
· ... 4097MiB 8191MiB → 成功,但可能弹 not properly aligned,回 Ignore

根因一句话:GPT 在磁盘末尾 33 个扇区(约 17KiB)放备份分区表 + 备份头,分区不能占。「到磁盘末尾」在分区世界里从来不是「到最后一个字节」。
-s 模式的坑:交互模式下 parted 会问 Fix/Ignore/Cancel?,选 Fix 它会自动把结尾收敛到 16777182;加了 -s 没人回答,它直接报错退出。-s ≠ 交互模式点 Fix。
对齐警告怎么办:512B/512B 的盘上偏 1 个扇区没有任何实际代价,选 Ignore 继续。但建好之后别回去重做——PV 已经压在上面了。

pvcreate + vgextend
partprobe /dev/sdc
pvcreate /dev/sdc2
vgextend rlm /dev/sdc2
vgs rlm
成功长什么样:Volume group "rlm" successfully extended;vgs rlm 的 VSize 变成 10.99g、VFree <4.00g、#PV 变成 2。
为什么 sdc2 是 4094MiB,VFree 却显示 <4.00g:4094 除 4MiB 是 1023.5 格,只取 1023 格 = 4092MiB = 3.996GiB,所以四舍五入显示 <4.00g。零头不足一格就被丢掉了,这是 PE 机制的正常损耗。
VFree 就是「还能借出去的格子总量」。看到它不是 0,就说明还能扩 LV;vgdisplay 里会用 Free PE / Size 单独列出来。
lvextend
lvextend -l +100%FREE /dev/rlm/root
lvs
成功长什么样:changed from <6.20 GiB (1586 extents) to 10.19 GiB (2609 extents) + successfully resized。此时 df 还是 6.2G。

-l +100%FREE 里的三个记号:-l 用 GE 计数 | + 增量(不是最终值)| 100%FREE 取卷组全部剩余格子(100%VG 则是整个卷组的大小,会把已有的也再算一遍,别混)。

swap 千万别碰:rlm 里还有 swap 820m。用 +100%FREE 只动空闲格子,swap 完全不受影响。如果写错成 -l +100%VG 会超配,命令会报错拒绝,但别去试。
xfs_growfs
xfs_growfs /
df -h /
成功长什么样:data blocks changed from 1624064 to 2671616;df -h / 的 Size 从 6.2G 变成 11G。
为什么参数是 / 而不是 /dev/mapper/rlm-root:xfs_growfs 要求在已挂载的文件系统上操作,它接受挂载点(也能吃设备路径,但挂载点更稳、不歧义)。根分区不能卸载,所以XFS 的在线扩容正是为这种场景设计的。
收尾
df -h /
findmnt /
lvs
vgs rlm
成功长什么样:df 显示 /dev/mapper/rlm-root 11G ... /;lvs 里 root 10.19g、swap 仍 820.00m;vgs rlm 的 VFree 变成 0。
fstab 一个字都不用改的原因:root 那条写的是 /dev/mapper/rlm-root,LV 名字由 LVM 元数据保证稳定;文件系统也没重建,UUID 不变。所以「给已有 LV 扩容」是唯一不需要动 fstab 的增容方式——这也是它和「加一块新盘」最大的区别(新盘必须写 fstab,否则重启就丢挂载)。
三个数字对不上,全是正常的:sdc2 4094MiB → VFree <4.00g(PE 取整丢零头)→ root 10.19g(账本精确值)→ df 11G(向上取整到整 G,还扣了 XFS 的 64MiB 日志和元数据)。方向记牢:df ≤ lvs,永远如此。反过来才是出事了。

5 · 实验 D:swap 它不是文件系统,也没有挂载点

目标:在 sdb 剩余空间建 512MiB swap,开机自动启用。这条线用的是一整套不同的命令——如果套用前面「mkfs + mount」的动作,到第一步就会卡住。

环节普通分区(实验 A/B)swap
建mkfs.xfsmkswap(没有「格式化」这个概念)
启用mount / mount -aswapon / swapon -a
fstab 第 2 字段目录路径none(不在文件树里)
fstab 第 6 字段0 或 2必须 0(swap 不做 fsck)
验收df / findmntfree -h / swapon --show(df 里永远看不到它)
最容易误判的一步:改完 swap 的 fstab 去跑 mount -a,什么都不会发生,也不报错。这不是命令坏了——mount 结构上就不处理 swap 条目,它需要一个挂载点,而 swap 没有。同理 swapon -a 也不会去动 /mnt/data。
parted print free
lsblk -f /dev/sdb
parted /dev/sdb unit mib print free
成功长什么样:sdb1 后面有一段 Free Space,记下它的起点 MiB(本机是 1025MiB)。下面所有数字都要换成你自己看到的。
不要照抄教程里的数字。分区起点差一个 MiB,parted 就会报 overlapping partitions 或者把起点挪到别的空位。
parted mkpart
parted /dev/sdb mkpart primary linux-swap 1025MiB 1537MiB
parted /dev/sdb unit mib print free
partprobe /dev/sdb
lsblk /dev/sdb
成功长什么样:出现 2 1025MiB 1537MiB 512MiB ... primary swap;lsblk 里 sdb2 大小 512M。
会弹两条警告,都选继续:
· The closest location we can manage is ... → parted 把起点后移了 1 个扇区,输 yes。
· not properly aligned for best performance → 输 ignore。
原因:上一分区的结束位置和新分区起点贴得太紧,parted 只能偏移 512 字节。512B 扇区的虚拟盘上没有实际代价;只有 4Kn 盘才需要在意。

为什么写 linux-swap:在 GPT 上它设置的是分区类型 GUID(等价于 msdos 的类型码 82),作用只是在分区表里做个标签,不写任何数据。真正的 swap 内容要靠下一步的 mkswap。

mkswap
mkswap /dev/sdb2
blkid /dev/sdb2
成功长什么样:Setting up swapspace version 1, size = 512 MiB (536866816 bytes) 加一行 UUID=...;blkid 出 TYPE="swap"。
字节数比 512MiB 少 4096:512MiB = 536870912,输出是 536866816。mkswap 在开头写了一页(4KiB)放自己的头。/proc/swaps 里也会同样少 4,这不是 bug。
又一次「blkid 有输出 ≠ 有文件系统」:swap 根本不是文件系统,blkid 照样打 TYPE。判断只能看值本身是不是你期望的那个。
六个字段逐个对
cp /etc/fstab /etc/fstab.$(date +%Y%m%d)
vi /etc/fstab
# 追加一行(UUID 换成 D3 的真实值):
# UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  none  swap  defaults  0 0

cat /etc/fstab
成功长什么样:cat 出来 6 个字段齐全 —— UUID 与 D3 一致、第 2 位 none、第 3 位 swap、最后一位 0。写完回读一遍。
备份带日期,不要覆盖:写成 /etc/fstab_bak 的话,第二次执行就会把上次那份好的覆盖掉。带 $(date +%Y%m%d) 才是真的留了后路。
swapon -a
swapon -a
swapon --show
free -h
cat /proc/swaps
成功长什么样:swapon -a 无任何输出;swapon --show 多出一行 /dev/sdb2 partition 512M 0B -3;free -h 的 Swap 从 820M 变成 1.3Gi。
两个容易误会的细节:
· swapon --show 里系统盘那块显示成 /dev/dm-1——它是内核临时编号,重启可能变 dm-2。fstab 里绝不能写 dm-N,要用 UUID 或 /dev/mapper/rlm-swap。
· PRIO -2 / -3 是自动分配的(负数=自动,后启用的低一档,数值越大越优先)。想让新盘先用,fstab 写 defaults,pri=10。
reboot
systemctl reboot
# 回来后,不要手工敲任何命令,直接看:
free -h
swapon --show
成功长什么样:Swap 仍是 1.3Gi,swapon --show 里仍有 sdb2,全程没有手工 swapon。
如果掉回 820M:fstab 那行有问题,但开机不会告诉你(错误只在 journal 里)。查 journalctl -b | grep -i swap。
为什么不写 fstab 也「能生效一辈子」:swapon -a 只在当前这次开机有效,重启即失。fstab 才是持久化的唯一位置。
swapoff / swapon -a
swapoff /dev/sdb2
free -h
swapon -a
free -h
成功长什么样:关掉后 Swap 掉回 820M,swapon -a 后回到 1.3Gi。掉的量和回来的量必须一致。

swapoff 不是改标记:它要把这块 swap 里的所有页搬回物理内存。内存不够时会很慢,甚至失败(搬迁无处可去)。这也是生产上关 swap 要挑时机的真实原因。

考试常出的另一半
dd if=/dev/zero of=/swapfile bs=1M count=512
chmod 600 /swapfile
mkswap /swapfile
restorecon -v /swapfile
swapon /swapfile
# fstab:/swapfile  none  swap  defaults  0 0
成功长什么样:ls -Z /swapfile 的类型是 swapfile_t;swapon --show 里 TYPE 列显示 file。
三个必踩的坑:
· 权限必须 600,644 会报 insecure permissions。
· Enforcing 下必须 restorecon,否则 swapon 被 SELinux 拒绝。
· XFS 上别用 fallocate 建 swap 文件——它生成 unwritten extents,swapon 报 Invalid argument,只能用 dd 实打实写。
状态:这一条尚未在本机实操过,属于「同一能力的另一半」,等有空再补。

6 · 附录一:四层命令对照表 建 / 看 / 拆,一层一套

层建看拆(由内向外)失败时先查
分区parted mkpartparted print free lsblkparted rm N是否被挂载 / 是否 PV
PVpvcreatepvs pvdisplaypvremove是否已入 VG(要先 vgreduce)
VGvgcreate vgextendvgs vgdisplayvgremove里面是否还有 LV
LVlvcreate lvextendlvs lvdisplaylvremove是否挂载 / 是否 swap 在用
文件系统mkfs.xfsblkid lsblk -f xfs_infowipefs -aTYPE 列有没有值
挂载fstab + mount -afindmnt df -hTumount + 删 fstab 行mount -a 的输出

一条贯穿全表的规则:建是由外向内(磁盘→分区→PV→VG→LV→FS→挂载),拆是由内向外(卸挂载→删 FS→删 LV→删 VG→删 PV→删分区)。方向反了必然报 in use。

7 · 附录二:报错速查 看到这行字该想到什么

报错 / 现象真实原因怎么处理
The location 8192mib is outside of the deviceGPT 尾部 33 扇区被备份表占着结尾写 8191MiB
... is not properly aligned for best performance分区起点没落在 1MiB 边界512B 盘上选 Ignore;4Kn 盘上应重做
No such file or directory(刚建完分区)内核还没重读分区表partprobe /dev/sdX
appears to contain an existing filesystem上面已有 FS 签名确认可覆盖后 mkfs.xfs -f
wrong fs type, bad option, bad superblockfstab 第 3 字段写错,或根本没 mkfsblkid 看真实 TYPE
can't find UUID=...UUID 抄错 / 分区被重建过重新 blkid 取值
mount point does not exist挂载点目录没建mkdir -p
target is busy / in use还有进程在用 / 还挂着umount,必要时 lsof +D
Logical volume ... in use(lvremove 时)还挂载着先 umount
New size ... exceeds ... free spaceVG 里格子不够vgs 看 VFree,先 vgextend
xfs_growfs: not a mounted XFS filesystem传了未挂载的设备或传错对象传挂载点,并确认已 mount
Filesystem should be larger than 300MB推荐值警告不是错误,继续
开机掉 emergency modefstab 里有挂不上的条目输入 root 密码 → mount -o remount,rw / → 修 fstab

8 · 附录三:十二条自测 先自己答,再展开

1. 分区表选 msdos 还是 gpt,判据是什么?

看整盘容量:超过 2TiB 必须 gpt(msdos 的 32 位 LBA 撑不住);不超过也建议 gpt,因为 GPT 有备份表、分区数不受 4 个主分区限制。注意 2T 说的是整盘,不是单个分区。

2. 为什么 parted 里「到 100%」会失败,而 gdisk/fdisk 却常常能建到最后?

因为 GPT 末尾固定保留 33 个扇区放备份分区表。parted 严格校验并拒绝越界;fdisk/gdisk 默认会自动把结尾往前收,所以看起来「能建」。本质是同一件事,只是谁替你收了这个边界。

3. 4096MiB 的分区做成 PV,为什么只有 1023 个 PE?

PV 头部元数据先占掉一部分,剩下才按 4MiB 切格子,不足一格被丢弃。1023 × 4MiB = 4092MiB,所以 vgs 显示 <4.00g。

4. lvextend 之后 df 没变,算成功还是失败?

成功。lvextend 只改 LVM 账本,文件系统还没接到「可以变大」的通知,必须再 xfs_growfs <挂载点>。df 变化才是最终验收。

5. -L 300MiB 和 -L +100MiB 差在哪?

前者是最终大小,后者是增量。题干说「增加到」用前者,「增加」用后者。-l 系列同理,但单位是 PE 格子数。

6. 扩完 LV 要不要改 fstab?新加一块盘要不要?

扩已有 LV 不用(设备名、UUID 都没变)。新加盘必须写,否则重启不挂载。区别就是「同一个设备变大了」和「多了一个设备」。

7. fstab 写完,为什么必须 mount -a 而不是等重启?

因为 fstab 有错时,开机过程会一直卡在挂载这一步,最终掉进 emergency mode,那时改文件很麻烦。mount -a 让错误现在、就在你能改文件的时候爆出来。

8. mount -a 没有任何输出,说明什么?

说明全部挂载成功。mount 系命令沉默即成功,看到输出反而是有问题。这条和 mkfs、parted 的成功行为一致:没消息就是好消息。

9. XFS 能缩小吗?ext4 呢?

XFS 不能缩,只能扩。ext4 可以缩,但要先卸载再 resize2fs,而且不能小于数据实际占用。所以「给根分区扩」是安全操作,「给根分区缩」基本等于重装。

10. 怎么一眼判断「分区建了但文件系统没建」?

lsblk -f:能看到分区行,但 FSTYPE 列为空。blkid 也可能什么都没有。lsblk 只看得到块设备结构,看不到文件系统 —— 这一列空着就是没 mkfs。

11. 改完 swap 的 fstab,为什么跑 mount -a 没反应?

因为 mount 需要挂载点,而 swap 的挂载点是 none,它根本不在文件树里。内核层面这是两条系统调用:mount(2) 和 swapon(2)。不是 mount 忽略了 swap,是结构上不适用。对应地,swapon -a 也不会去处理普通挂载条目。

12. 分区表里标了 swap,是不是就表示这块已经是 swap 了?

不是。那是两套互不校验的信息:分区表里的类型只是标签(parted print 的 Flags 列),mkswap 写在分区开头 4KiB 的签名才是内核认的东西(blkid 的 TYPE="swap")。只标不打签名 → swapon 失败;只打签名不标 → swapon 照样成功。