从一份 fdisk 输出读懂磁盘扩容
一、先看现场
下面是一台 openEuler 云主机上的 fdisk -l 输出。开头两行警告看着吓人,其实不是故障,它们说明这块盘刚扩过容,系统还没跟上。
1 | GPT PMBR size mismatch (20971519 != 83886079) will be corrected by write. |
接下来先逐段拆解,再从数字推算发生了什么,最后给出扩容步骤。
二、逐段拆解
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

把几个数字串起来:
- PMBR 记录的最后扇区是 20971519,说明磁盘当时有 20971520 个扇区,乘以 512 字节正好是 10 GiB。
- 磁盘现在有 83886080 个扇区,即 40 GiB。也就是说,分区表是按 10G 的磁盘写的,而磁盘现在是 40G。常见原因有两种:在云平台或虚拟化层把磁盘从 10G 扩到了 40G,或者用 10G 的系统镜像创建了一块 40G 的磁盘。
- 磁盘变大时,分区表不会自动跟着更新。PMBR 和备份 GPT 表头都还停在 10G 时的位置,于是出现了那两行警告。
- vda3 结束于 20969471 扇区,也就是旧磁盘末尾附近。它后面约 30 GiB 是未分配空间,没有分区在用。
- 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. 操作步骤
- 安装 growpart:它在 cloud-utils-growpart 包里。
1 | dnf install -y cloud-utils-growpart |
- 扩展 vda3 分区:growpart 会把分区延伸到磁盘末尾,同时把备份 GPT 表头移到新的末尾。注意磁盘名和分区号之间有空格。
1 | growpart /dev/vda 3 |
如果只想修复 GPT、不扩分区,可以用 sgdisk -e /dev/vda,或者执行 parted /dev/vda print,在提示时选 Fix。
扩展完成后,分区前后比较如下:

- 扩展 LVM 物理卷:让 LVM 识别 vda3 的新大小。
1 | pvresize /dev/vda3 |
- 扩展逻辑卷和文件系统:把卷组里的空闲空间全部分给 root。
-r会自动调用对应的文件系统扩容工具。
1 | lvextend -r -l +100%FREE /dev/openeuler/root |
不加 -r 的话要手动扩文件系统:XFS 用 xfs_growfs /,ext4 用 resize2fs /dev/openeuler/root。openEuler 默认是 XFS,可以用 df -T / 确认。
- 验证:再执行一次
fdisk -l,两行警告应该消失,vda3 约 38.4G;df -h /应显示根分区约 37G。
五、更清晰的看法:用 lsblk
fdisk -l 把所有块设备平铺成一长串,层级关系要自己拼。日常查看结构更适合用 lsblk,它把磁盘、分区、LVM 画成一棵树。同一台机器在扩容前大致是这样:
1 | NAME SIZE TYPE MOUNTPOINTS |
从这里能直接看到:磁盘 40G,三个分区加起来只有 10G,mapper 设备是 vda3 的子节点。
常用的补充命令:
fdisk -l /dev/vda:只看一块盘,避免 mapper 设备干扰。lsblk -f:加上文件系统类型和 UUID。pvs、vgs、lvs:查看 LVM 各层的容量和空闲空间。
六、小结
fdisk -l 只把设备逐个列出来,不显示它们之间的关系,所以看着乱。读的时候拿扇区数对一对:磁盘多大,分区在哪里结束,分区表头记录的又是多大。对上之后就能看出,那两行警告只是说明扩容还没做完。