上个月我的 VPS 突然报警,说根分区使用率超过 90%。登上去一看,/ 目录只剩几百兆了,连 apt 更新都跑不动。这台机器装了很多 Docker 容器和数据库,空间消耗比我想象的快得多。

如果是普通分区,扩容可能还要折腾数据迁移。但好在当时装机的时候用了 LVM,扩容相对来说简单很多。这篇文章就记录一下我那次 LVM 扩容的完整过程。

什么是 LVM

LVM 全称 Logical Volume Manager,逻辑卷管理。它把物理磁盘、分区抽象成物理卷(PV)、卷组(VG)、逻辑卷(LV)三层。

简单理解:

  • 物理卷 PV:就是实际的磁盘或分区。
  • 卷组 VG:把多个物理卷合并成一个"池子"。
  • 逻辑卷 LV:从卷组里划分出来的逻辑分区,最后格式化文件系统挂载使用。

好处是扩容特别灵活。物理磁盘不够了,可以加一块新盘,把它加入卷组,然后直接扩展逻辑卷,不需要重新分区或者迁移数据。

先确认当前磁盘布局

扩容之前一定要先搞清楚现在的结构,不然很容易扩错地方。

查看物理卷:

1pvdisplay

查看卷组:

1vgdisplay

查看逻辑卷:

1lvdisplay

我当时的结构大概是这样:

  • 物理卷 /dev/vda2,大小 30G
  • 卷组 ubuntu-vg,包含 /dev/vda2
  • 逻辑卷 /dev/ubuntu-vg/ubuntu-lv,挂载到 /,已用 28G

也就是说,整台机器实际上只有一个根分区,所有东西都在里面。

方案选择

当时有两种方案:

  1. 在线扩容虚拟磁盘:我的 VPS 服务商支持直接扩容云盘,扩容后在系统里扩展 LVM 即可。
  2. 加一块新数据盘:再买一块数据盘挂上去,把 /var/lib/docker 这种大目录迁移过去。

我选了第一种,因为比较省事,而且 / 下数据分散,单独迁某个目录后面维护起来麻烦。

在 VPS 控制台把磁盘从 30G 扩容到 60G 之后,登录系统开始操作。

第一步:确认磁盘已经变大

1lsblk

或者:

1fdisk -l

应该能看到 /dev/vda 总容量变成了 60G,但分区 /dev/vda2 还是 30G。因为分区表没有更新。

第二步:扩展物理分区

这一步比较关键,也最容易出错。因为 /dev/vda2 是正在使用的根分区,普通情况下没法直接调整。但现在很多工具支持在线扩展。

我用的 growpart,它是 cloud-utils 包里的工具:

1apt update
2apt install cloud-guest-utils -y
3growpart /dev/vda 2

注意 /dev/vda 2 中间有空格,表示第 2 个分区。执行完之后,再用 lsblk 看,/dev/vda2 应该已经变成 60G 了。

如果你的系统没有 growpart,也可以用 parted 或者重启后用 live CD 调整。但 growpart 最方便,推荐先试试这个。

第三步:扩展物理卷 PV

现在物理分区变大了,但 PV 还没有意识到。要让 LVM 识别新的空间:

1pvresize /dev/vda2

然后 pvdisplay 看一下,Free PE 应该多了 30G 的可用空间。

第四步:扩展逻辑卷 LV

把卷组里的空闲空间分配给逻辑卷。我的逻辑卷路径是 /dev/ubuntu-vg/ubuntu-lv

1lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

-l +100%FREE 表示把卷组里所有剩余空间都给它。如果你想指定大小,也可以用 -L +30G

第五步:扩展文件系统

LVM 扩展完之后,文件系统还没有变大,最后一步要扩容文件系统。

如果文件系统是 ext4:

1resize2fs /dev/ubuntu-vg/ubuntu-lv

如果文件系统是 xfs:

1xfs_growfs /

我的系统是 ext4,所以用 resize2fs。这个命令可以在线执行,不需要卸载分区。

第六步:验证

最后用 df -h 看一下:

1df -h /

根分区应该已经从 30G 变成 60G 了,而且数据都还在,不需要重启。

一个容易忽略的点

扩容的时候一定要先确认文件系统类型。我有一次想当然地用了 resize2fs,结果文件系统是 xfs,命令直接报错。虽然没造成损失,但浪费了不少时间。

查看文件系统类型:

1df -Th

或者:

1lsblk -f

如果没有用 LVM 怎么办

如果你的根分区不是 LVM,而是普通分区,扩容会麻烦一些。一般来说需要:

  1. 备份数据。
  2. 用 live CD 或者救援模式启动。
  3. 调整分区大小。
  4. 扩容文件系统。

这也是为什么我现在装机尽量用 LVM 的原因。虽然一开始看起来多了一层抽象,但后续扩容真的省很多事。

总结

LVM 扩容的完整流程就是:

  1. growpart 扩展物理分区
  2. pvresize 扩展物理卷
  3. lvextend 扩展逻辑卷
  4. resize2fsxfs_growfs 扩展文件系统

整个过程不需要停机,数据也不会丢失。但还是要提醒一句:扩容前一定要先快照备份。虽然我这次很顺利,但磁盘操作毕竟有风险,养成备份习惯不吃亏。

另外,扩容只是治标。如果磁盘空间持续快速增长,还是要找到真正占空间的元凶,比如日志失控、Docker 镜像堆积、数据库膨胀这些。不然扩到 100G 也很快又满了。