0%

从一份 fdisk 输出读懂磁盘扩容

从一份 fdisk 输出读懂磁盘扩容

一、先看现场

下面是一台 openEuler 云主机上的 fdisk -l 输出。开头两行警告看着吓人,其实不是故障,它们说明这块盘刚扩过容,系统还没跟上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GPT PMBR size mismatch (20971519 != 83886079) will be corrected by write.
The backup GPT table is not on the end of the device.
Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors
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: gpt
Disk identifier: CD207D85-A191-464B-8C32-83D0A12A7A2A

Device Start End Sectors Size Type
/dev/vda1 2048 1230847 1228800 600M EFI System
/dev/vda2 1230848 3327999 2097152 1G Linux filesystem
/dev/vda3 3328000 20969471 17641472 8.4G Linux LVM

Disk /dev/mapper/openeuler-root: 7.41 GiB, 7956594688 bytes, 15540224 sectors
...
Disk /dev/mapper/openeuler-swap: 1 GiB, 1073741824 bytes, 2097152 sectors
...

接下来先逐段拆解,再从数字推算发生了什么,最后给出扩容步骤。

二、逐段拆解

1. 两行警告:是提醒,不是报错

GPT 在磁盘上存了两份分区信息:开头是第 0 扇区的保护性 MBR(PMBR)、LBA 1 的主 GPT 表头和紧随其后的分区项数组;末尾是备份分区项数组,以及放在最后一个扇区的备份 GPT 表头。

  • GPT PMBR size mismatch (20971519 != 83886079):PMBR 记录的最后一个扇区是 20971519,磁盘实际的最后一个扇区是 83886079,两者对不上。
  • The backup GPT table is not on the end of the device:备份表头还在旧的末尾位置,不在现在的末尾。

will be corrected by write 是说用 fdisk 写一次分区表,它就会自动修正。fdisk -l 只读不写,所以每次执行都会看到这两行,数据本身没有风险。

2. 磁盘头信息

字段 本例取值 含义
Disk 40 GiB,83886080 扇区 磁盘当前的实际容量
Units 512 字节 下方 Start/End/Sectors 的单位
Sector size 512 / 512 逻辑扇区和物理扇区大小,虚拟盘常见为 512
I/O size 512 / 512 建议的最小和最佳 I/O 大小,影响分区对齐
Disklabel type gpt 分区表类型,另一种常见的是 dos(MBR)
Disk identifier CD207D85-… 磁盘的 GPT GUID

3. 分区表

三个分区是典型的 UEFI + LVM 安装布局。第一个分区从 2048 扇区(1 MiB)开始,这是为了对齐。

分区 大小 类型 用途
/dev/vda1 600 MiB EFI System 挂载到 /boot/efi
/dev/vda2 1 GiB Linux filesystem 挂载到 /boot
/dev/vda3 8.4 GiB Linux LVM LVM 物理卷(PV)

注意 vda3 结束于 20969471 扇区,而磁盘有 83886080 个扇区,这个差距下一节会用到。

4. /dev/mapper 设备:最容易让人困惑的部分

openeuler-root 和 openeuler-swap 不是另外两块磁盘,是从 vda3 这个 LVM 物理卷里切出来的逻辑卷(LV)。fdisk 会把所有块设备都列成 “Disk”,所以它们和 vda 并排出现。逻辑卷上直接就是文件系统或 swap,没有分区表,所以也没有 Disklabel type 这一行,这是正常的。

三、推理:分区表还停在 10G

把几个数字串起来:

  1. PMBR 记录的最后扇区是 20971519,说明磁盘当时有 20971520 个扇区,乘以 512 字节正好是 10 GiB。
  2. 磁盘现在有 83886080 个扇区,即 40 GiB。也就是说,分区表是按 10G 的磁盘写的,而磁盘现在是 40G。常见原因有两种:在云平台或虚拟化层把磁盘从 10G 扩到了 40G,或者用 10G 的系统镜像创建了一块 40G 的磁盘。
  3. 磁盘变大时,分区表不会自动跟着更新。PMBR 和备份 GPT 表头都还停在 10G 时的位置,于是出现了那两行警告。
  4. vda3 结束于 20969471 扇区,也就是旧磁盘末尾附近。它后面约 30 GiB 是未分配空间,没有分区在用。
  5. root(7.41 GiB)加 swap(1 GiB)约等于 vda3 的 8.41 GiB,差出的一点是 LVM 元数据和对齐占用。所以卷组里也没有空闲空间。

结论:df -h 里根分区仍然是 7G 多,新增的 30G 完全闲置。要用上这部分空间,需要从下到上逐层扩展:GPT → 分区 → PV → LV → 文件系统。

四、在线扩容:从分区到文件系统逐层扩展

操作前先在云平台给磁盘打一个快照。以下步骤都可以在线完成,不用重启。

在线扩容的操作步骤

1. 为什么不能跳过 growpart

每一层只认它正下方那一层的大小:文件系统看 LV,LV 看 VG,PV 看它所在的分区。这里 PV 建在 vda3 上,而 vda3 在分区表里仍是 8.4G,新增的 30G 在分区之外。跳过 growpart 直接执行 pvresize,PV 大小不会变化。所以必须先扩分区,上面几层才有空间可扩。

有两种情况可以不用 growpart:

  • PV 直接建在整块盘上(当初执行的是 pvcreate /dev/vda,没有分区):磁盘扩容后直接 pvresize /dev/vda 即可。数据盘常这样做,系统盘因为有 EFI 和 /boot 分区,一般不适用。
  • 无法安装 growpart:可以不扩 vda3,改用系统自带的 fdisk 在空闲空间里新建 vda4,再执行 pvcreate /dev/vda4 和 vgextend openeuler /dev/vda4,然后从第 4 步 lvextend 继续。代价是卷组里会多出一个 PV。

2. 操作步骤

  1. 安装 growpart:它在 cloud-utils-growpart 包里。
1
dnf install -y cloud-utils-growpart
  1. 扩展 vda3 分区:growpart 会把分区延伸到磁盘末尾,同时把备份 GPT 表头移到新的末尾。注意磁盘名和分区号之间有空格。
1
growpart /dev/vda 3

如果只想修复 GPT、不扩分区,可以用 sgdisk -e /dev/vda,或者执行 parted /dev/vda print,在提示时选 Fix。

扩展完成后,分区前后比较如下:

growpart 前后的分区变化

  1. 扩展 LVM 物理卷:让 LVM 识别 vda3 的新大小。
1
pvresize /dev/vda3
  1. 扩展逻辑卷和文件系统:把卷组里的空闲空间全部分给 root。-r 会自动调用对应的文件系统扩容工具。
1
lvextend -r -l +100%FREE /dev/openeuler/root

不加 -r 的话要手动扩文件系统:XFS 用 xfs_growfs /,ext4 用 resize2fs /dev/openeuler/root。openEuler 默认是 XFS,可以用 df -T / 确认。

  1. 验证:再执行一次 fdisk -l,两行警告应该消失,vda3 约 38.4G;df -h / 应显示根分区约 37G。

五、更清晰的看法:用 lsblk

fdisk -l 把所有块设备平铺成一长串,层级关系要自己拼。日常查看结构更适合用 lsblk,它把磁盘、分区、LVM 画成一棵树。同一台机器在扩容前大致是这样:

1
2
3
4
5
6
7
NAME               SIZE TYPE MOUNTPOINTS
vda 40G disk
├─vda1 600M part /boot/efi
├─vda2 1G part /boot
└─vda3 8.4G part
├─openeuler-root 7.4G lvm /
└─openeuler-swap 1G lvm [SWAP]

从这里能直接看到:磁盘 40G,三个分区加起来只有 10G,mapper 设备是 vda3 的子节点。

常用的补充命令:

  • fdisk -l /dev/vda:只看一块盘,避免 mapper 设备干扰。
  • lsblk -f:加上文件系统类型和 UUID。
  • pvs、vgs、lvs:查看 LVM 各层的容量和空闲空间。

六、小结

fdisk -l 只把设备逐个列出来,不显示它们之间的关系,所以看着乱。读的时候拿扇区数对一对:磁盘多大,分区在哪里结束,分区表头记录的又是多大。对上之后就能看出,那两行警告只是说明扩容还没做完。