在使用 Linux 虚拟机进行开发时,经常会遇到磁盘空间不足的问题。比如编译大型工程、安装大量开发工具、保存源码和构建产物后,根文件系统很容易被占满。
需要注意的是:在 VirtualBox、VMware 等虚拟化软件中扩大虚拟硬盘容量后,Linux 并不会自动扩大根分区和文件系统。
完整的扩容过程实际上分为几个层次:
虚拟磁盘
↓
分区表
↓
根分区
↓
文件系统
只有每一层都完成扩容,最终 / 才能真正获得新增空间。
一、先理解 Linux 磁盘扩容的结构
假设原来的虚拟硬盘是 100GB:
/dev/sda 100GB
├── /dev/sda1
├── /dev/sda2 /boot/efi
└── /dev/sda3 /
后来在虚拟机管理软件中把磁盘扩大到了 500GB:
/dev/sda 500GB
├── /dev/sda1
├── /dev/sda2 /boot/efi
└── /dev/sda3 / 100GB
│
└── 剩余约 400GB 未分配
此时 Linux 看到的硬盘已经是 500GB,但根分区仍然只有约 100GB。
因此:
df -h
仍然只能看到大约 100GB。
这并不是虚拟机扩容失败,而是因为新增的磁盘空间还没有分配给根分区和文件系统。
二、第一步:确认当前磁盘结构
扩容之前首先要确认当前磁盘到底是什么结构。
推荐:
lsblk -f
查看文件系统和挂载点:
df -hT
查看分区表:
sudo fdisk -l
例如:
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1
├─sda2 vfat FAT32 xxxx 500M 1% /boot/efi
└─sda3 ext4 1.0 xxxx 18G 81% /
同时:
Disk /dev/sda: 500 GiB
这说明:
- 虚拟硬盘已经是 500GB
sda2是 EFI 分区sda3是根分区- 根文件系统是 ext4
- 但
sda3可能仍然只有原来的 100GB
这时就需要继续扩展。
三、虚拟磁盘扩大后,GPT 可能需要修复
如果使用的是 GPT 分区表,扩大虚拟硬盘后,有时会看到:
GPT PMBR size mismatch
The backup GPT table is not on the end of the device.
这是因为:
原始磁盘:
GPT认为磁盘只有100GB
实际磁盘:
现在已经500GB
磁盘尾部的 GPT 备份分区表仍然位于原来的位置。
可以使用 sgdisk 修复:
sudo sgdisk -e /dev/sda
这里的 -e 会将 GPT 备份数据结构移动到磁盘的新末尾。
完成后可以重新检查:
sudo fdisk -l /dev/sda
确认相关 GPT 警告已经消失。
四、扩大根分区
修复分区表之后,还需要把新增空间分配给根分区。
Ubuntu 中可以使用 growpart。
首先确认是否安装:
which growpart
如果没有:
sudo apt install cloud-guest-utils
然后假设根分区是 /dev/sda3:
sudo growpart /dev/sda 3
这里需要特别注意命令格式:
/dev/sda
↑
整个磁盘
3
↑
第3个分区
也就是说:
sudo growpart /dev/sda 3
表示:
将
/dev/sda的第 3 个分区扩展到后面的可用空间。
扩容后可以检查:
lsblk
或者:
sudo fdisk -l /dev/sda
此时应该看到 sda3 已经接近整个磁盘的容量。
五、最后扩大文件系统
这是很多人最容易遗漏的一步。
即使:
/dev/sda3
已经扩大了,里面的 ext4 文件系统仍然可能保持原来的容量。
例如:
分区:500GB
文件系统:100GB
所以还需要扩大文件系统。
对于 ext4:
sudo resize2fs /dev/sda3
resize2fs 会把 ext4 文件系统扩展到所在分区能够提供的最大空间。
完成后:
df -hT /
就可以看到新的容量。
六、完整扩容流程
对于最常见的:
GPT
+
普通分区
+
ext4
+
根分区位于磁盘末尾
可以总结成:
① 在 VirtualBox/VMware 中扩大虚拟磁盘
↓
② 检查磁盘
lsblk -f
df -hT
sudo fdisk -l
↓
③ 如果 GPT 没有扩展到磁盘末尾
sudo sgdisk -e /dev/sda
↓
④ 扩大根分区
sudo growpart /dev/sda 3
↓
⑤ 扩大 ext4 文件系统
sudo resize2fs /dev/sda3
↓
⑥ 验证
df -hT /
可以简单记成:
磁盘 → 分区 → 文件系统
每一层都要扩。
七、为什么不能只执行 resize2fs?
例如当前:
/dev/sda3 = 100GB
即使虚拟磁盘已经变成:
/dev/sda = 500GB
如果 sda3 还是 100GB,那么:
sudo resize2fs /dev/sda3
最多只能把文件系统扩展到 sda3 当前允许的范围。
它不会自动修改分区表。
所以正确顺序是:
扩大分区
↓
扩大文件系统
而不是直接扩大文件系统。
八、如果使用的是 LVM,方法不同
上面的流程适用于普通分区。
如果:
lsblk
看到类似:
sda
├── sda1
└── sda2
└── ubuntu-vg
└── ubuntu-lv /
说明系统使用了 LVM。
这时候扩容链路变成:
虚拟磁盘
↓
分区
↓
Physical Volume
↓
Volume Group
↓
Logical Volume
↓
文件系统
典型流程可能是:
sudo growpart /dev/sda 2
sudo pvresize /dev/sda2
sudo lvextend -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv
最后根据文件系统类型扩容。
ext4:
sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
XFS:
sudo xfs_growfs /
因此,扩容之前一定要先用 lsblk -f 判断是不是 LVM。
九、不同文件系统使用不同的扩容工具
常见情况:
| 文件系统 | 扩容命令 |
|---|---|
| ext4 | resize2fs |
| XFS | xfs_growfs |
| Btrfs | btrfs filesystem resize |
例如:
df -T /
如果看到:
ext4
使用:
sudo resize2fs /dev/sda3
如果看到:
xfs
则不能使用 resize2fs,而应该使用:
sudo xfs_growfs /
十、扩容后一定要验证
完成扩容后建议检查三个层次。
1. 检查磁盘
lsblk
2. 检查分区
sudo fdisk -l /dev/sda
3. 检查文件系统
df -hT /
例如最终可能看到:
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda3 ext4 490G 75G 390G 17% /
这就说明扩容已经完整完成。
十一、磁盘满导致的问题不只是无法保存文件
Linux 根文件系统空间不足时,影响可能非常广泛。
例如:
Vim 无法创建 swap 文件
可能出现:
E514: write error
或者:
E297: Write error in swap file
除此之外,还可能导致:
- 软件包安装失败
- 日志无法写入
- 编译失败
- Git 操作异常
- 临时文件无法创建
- 数据库无法写入
- 服务启动失败
- 系统出现各种看似无关的错误
因此遇到一些奇怪的 I/O、写文件失败问题时,可以先检查:
df -h
以及:
df -i
后者用于检查 inode 是否耗尽。
十二、实际排查时建议形成固定习惯
遇到 Linux 磁盘空间不足,推荐按照下面的顺序处理:
df -h
确认是不是容量满了。
然后:
df -i
确认是不是 inode 用完了。
再:
lsblk -f
确认磁盘、分区、文件系统结构。
最后:
sudo fdisk -l
确认磁盘实际容量和分区布局。
如果刚刚在虚拟机软件中扩大过磁盘,则重点确认:
磁盘容量
↓
分区容量
↓
文件系统容量
三者是否一致。
十三、最重要的经验总结
Linux 虚拟机扩容并不是简单的“把硬盘改大”。
完整过程可以记成一句话:
先扩大虚拟磁盘,再扩大分区,最后扩大文件系统。
对于普通 GPT + ext4 分区:
# 1. 修复 GPT(如果需要)
sudo sgdisk -e /dev/sda
# 2. 扩大第 3 个分区
sudo growpart /dev/sda 3
# 3. 扩大 ext4 文件系统
sudo resize2fs /dev/sda3
# 4. 验证
df -hT /
而在实际操作之前,永远先执行:
lsblk -f
df -hT
sudo fdisk -l
先确定自己的磁盘结构,再决定扩容方案。
这次遇到的 Vim .swp 问题也是一个很典型的例子:**表面上看是 Vim 的问题,实际上根因是根文件系统空间不足。**遇到 Linux 异常时,先检查 df -h 往往能快速排除一大类问题。