运维工作中,磁盘空间不足是最常见的"慢性病"之一。如何安全地将未分配空间"还给"根分区?本文记录了一次真实的 ext4 文件系统根目录扩容全过程,从问题诊断到最终验证,每一步都附带原理说明,希望能为遇到类似问题的同学提供参考。
1、问题背景
- 某台 Linux 服务器在初始化时,系统盘(vda)分配了 100G,但根分区(/dev/vda2)仅使用了约 20G,剩余约 80G 处于未分配状态。随着业务运行,根目录空间逐渐吃紧,需要将这些未分配空间扩容到根分区。
- 环境信息
| 项目 | 详情 |
|---|---|
| 操作系统 | CentOS / RHEL 系 |
| 磁盘 | /dev/vda,100G(GPT 分区表) |
| 根分区 | /dev/vda2,19.5G,ext4 文件系统 |
| 数据盘 | /dev/vdb,100G,独立挂载在 /data,不受影响 |
2、问题诊断
2.1、查看磁盘和分区情况
bash
# 命令
lsblk
# 输出
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 100G 0 disk
├─vda1 253:1 0 500M 0 part /boot/efi
└─vda2 253:2 0 19.5G 0 part /
vdb 253:16 0 100G 0 disk
└─vg_data-lv_data 252:0 0 100G 0 lvm /data
# 可以看到 vda 总共 100G,但 vda2 只有 19.5G,说明有大量空间未分配
2.2、查看文件系统使用情况
bash
# 命令
df -h
# 输出
Filesystem Size Used Avail Use% Mounted on
/dev/vda2 20G 8.4G 9.8G 47% /
/dev/vda1 500M 6.8M 493M 2% /boot/efi
/dev/mapper/vg_data-lv_data 100G 746M 100G 1% /data
# 根目录已使用 47%,随着日志和容器镜像的积累,剩余空间随时可能告急
2.3、用 fdisk 确认未分配空间
bash
# 命令
fdisk -l /dev/vda
# 输出关键信息
GPT PMBR size mismatch (41943039 != 209715199) will be corrected by write.
The backup GPT table is not on the end of the device.
Disk /dev/vda: 100 GiB, 107374182400 bytes, 209715200 sectors
Device Start End Sectors Size Type
/dev/vda1 2048 1026047 1024000 500M EFI System
/dev/vda2 1026048 41940991 40914944 19.5G Linux filesystem
3、扩容操作说明
3.1、扩容步骤
a、扩展分区:修改分区表,让 vda2 的边界延伸到磁盘末尾
b、刷新内核分区表:让内核感知到分区大小的变化
c、扩展文件系统:让 ext4 文件系统识别并使用新增的空间
PS:为什么不用 LVM? 因为根分区是直接使用物理分区(/dev/vda2),没有经过 LVM 层,所以不需要 pvcreate、vgextend 等操作,直接扩展分区和文件系统即可。
PS:了解 LVM 如何扩容? 可见博客:【Linux】Linux 虚拟机磁盘扩容全攻略_linux虚拟机磁盘扩容-CSDN博客
3.2、具体操作步骤
步骤 1:扩展分区(使用 fdisk)
bash
# 选择用 fdisk 手动操作,因为它对 GPT 分区表的支持更可靠
fdisk /dev/vda
# 进入交互界面后,依次执行以下操作
## 打印当前分区表,记录 vda2 的 Start 扇区(本例中是 1026048)。这个数值在后续操作中必须保持一致
Command (m for help): p
## 删除分区 2,不用担心,删除分区只是从分区表中移除记录,不会清除分区上的实际数据
Command (m for help): d
Partition number (1,2, default 2): 2
## 新建分区,关键要点
### First sector:必须与原来相同(1026048),如果改变起始位置,文件系统会找不到,数据全丢
### Last sector:默认值(磁盘末尾),让分区占用所有剩余空间
Command (m for help): n
Partition number (2-128, default 2): 2
First sector (1026048-209715166, default 1026048): 1026048
Last sector (1026048-209715166, default 209715166): [直接回车]
## 当 fdisk 询问是否移除文件系统签名时,选择 N,保留现有的 ext4 文件系统签名
Do you want to remove the signature? [Y]es/[N]o: N
## 写入分区表并退出,fdisk 会提示:The partition table has been altered.Calling ioctl() to re-read partition table.
Command (m for help): w
步骤 2:刷新分区表
bash
partprobe /dev/vda
# 如果提示设备忙(device is busy),说明分区正在被使用,需要重启
reboot
# 重启后验证,此时应该看到 vda2 的大小已经变为约 99.5G
lsblk | grep vda2
步骤 3:扩展 ext4 文件系统
bash
# 分区扩展了,但文件系统还不知道,使用 resize2fs 让 ext4 在线扩展到分区的最大容量
resize2fs /dev/vda2
# 输出
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/vda2 is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 13
The filesystem on /dev/vda2 is now 26188539 blocks long.
# PS
## 为什么用 resize2fs? 因为根分区使用的是 ext4 文件系统。resize2fs 是 ext2/ext3/ext4 文件系统专用的在线扩容工具,可以在分区挂载状态下直接扩展,无需卸载
步骤 4:验证结果
bash
# 命令
df -h /
# 输出
Filesystem Size Used Avail Use% Mounted on
/dev/vda2 99G 8.4G 86G 9% /
# 命令
lsblk
# 输出
vda 253:0 0 100G 0 disk
├─vda1 253:1 0 500M 0 part /boot/efi
└─vda2 253:2 0 99.5G 0 part /

