LVM 逻辑卷在线扩容与缩容完整流程(含文件系统配合)

磁盘空间告警是运维最日常的工单之一。用了 LVM 的主机,扩容可以在不停业务的情况下完成,但前提是分清「卷扩了」和「文件系统扩了」是两件事,且缩容远比扩容危险。本文以 Rocky Linux 9 为例,走通在线扩容完整链路,并说明缩容的限制与正确做法。

前置条件

  • 目标卷为 LVM 管理(lsblk 能看到 TYPE 为 lvm 的设备),有 root 或 sudo 权限;
  • 已准备新磁盘或云盘已扩容(示例新增磁盘 /dev/vdb,20G);
  • 扩容前确认业务低峰期操作,缩容前必须有可用备份;
  • 知道目标文件系统类型:df -Th 先看清是 xfs 还是 ext4,后文流程区别很大。

概念速览:PV、VG、LV 三层

物理卷 PV 是被 LVM 接管的磁盘或分区,卷组 VG 是把若干 PV 汇成的存储池,逻辑卷 LV 是从池里切出来、最终格式化挂载的「分区」。所以扩容的本质是三步:给池子加料(新 PV 加入 VG)→ 从池子多切一块给 LV → 让 LV 上的文件系统长满新空间。任何一步没做完,df 看到的都还是旧容量。

第一步:加盘并创建物理卷

lsblk                       # 确认新盘设备名,别凭记忆写
sudo pvcreate /dev/vdb      # 整盘做 PV,云盘场景最常见
sudo pvs                    # 确认 PV 已出现,PSize 正确

如果是给已有云盘在线扩容(盘还是同一块、容量变大了),顺序不同:先 echo 1 > /sys/class/block/vdb/device/rescan 让内核感知新容量,整盘 PV 用 pvresize /dev/vdb;分区型 PV 则先用 growpart 扩分区再 pvresize。云盘扩容后 lsblk 显示新容量、pvs 还是旧值,基本都是漏了 pvresize。

第二步:扩展卷组与逻辑卷

sudo vgextend vg_data /dev/vdb
sudo vgs                    # 看 VFree 是否增加了约 20G
sudo lvextend -L +20G /dev/vg_data/lv_data
# 或吃掉全部剩余空间: sudo lvextend -l +100%FREE /dev/vg_data/lv_data
sudo lvs                    # 确认 LV 容量已变大

到这一步只是块设备变大了,文件系统还没动,df -h 显示的仍是旧容量,这是正常现象,不要误以为失败。

第三步:扩展文件系统(xfs 与 ext4 的区别)

这一步是整条链路最容易出错的地方,两个工具不能混用:

# xfs:对挂载点操作,在线执行,要求文件系统处于挂载状态
sudo xfs_growfs /data

# ext4:对 LV 设备操作,在线、挂载状态下同样可扩
sudo resize2fs /dev/vg_data/lv_data

区别记牢:xfs_growfs 的参数是挂载点、只能扩不能缩;resize2fs 的参数是设备、扩缩都支持。偷懒办法是扩容时直接给 lvextend 加 -r 参数,它会自动调用对应的文件系统扩展工具:

sudo lvextend -r -L +20G /dev/vg_data/lv_data

生产上推荐显式分两步执行,每步都能停下来检查;-r 适合流程熟练后的批量脚本。

验证

df -h /data        # 容量应已变为新值
sudo lvs && sudo vgs
findmnt /data

预期:df 显示新容量且可用空间同步增加,lvs 中 LV 尺寸与预期一致,业务进程无需重启即可写入新空间。

缩容:限制、风险与正确姿势

缩容和扩容完全不是一个风险等级,先明确三条铁律:

  • xfs 不支持缩容,没有任何官方工具能做。xfs 卷想变小,只能新建小卷、迁移数据、切换挂载。
  • ext4 缩容必须离线:卸载文件系统后,先缩文件系统、再缩 LV,顺序反了必坏数据。
  • 先看已用量:目标容量必须大于已用数据量并留足余量,先 df -h 和 du 摸清。

ext4 缩容示例(把 lv_data 缩到 30G,务必在维护窗口操作):

sudo umount /data
sudo e2fsck -f /dev/vg_data/lv_data        # 强制检查,不可跳过
sudo resize2fs /dev/vg_data/lv_data 28G    # 文件系统先缩,且小于目标 LV
sudo lvreduce -L 30G /dev/vg_data/lv_data  # 再缩 LV,会二次确认
sudo resize2fs /dev/vg_data/lv_data        # 长回 LV 的实际大小
sudo mount /data && df -h /data

文件系统故意先缩到比 LV 目标更小(28G < 30G),是为两步之间的对齐误差留安全边际。此外 lvreduce 有 -r 可以联动先缩文件系统,但手工分步在排障时更清楚每一步发生了什么。

快照的临时用途

做高风险操作前,可以给 LV 打一个快照作为短时回滚点:

sudo lvcreate -L 5G -s -n lv_data_snap /dev/vg_data/lv_data

快照是写时复制:原卷写得越多、快照占用越大,写满即失效。它只适合「操作后观察几小时到几天」这种临时保险,不能当备份:原盘坏了快照一起没,且长期挂快照会拖慢写性能。验证无误后及时删除:sudo lvremove /dev/vg_data/lv_data_snap;真要回滚则用 lvconvert --merge(需要先卸载)。

常见问题

  • lvextend 报错 Insufficient free space:VG 里没空闲了,根因在上游——新盘没 pvcreate、或 pvcreate 了没 vgextend。按 PV→VG→LV 顺序用 pvs/vgs 逐层核对。
  • 扩完 df 还是旧容量:99% 是漏了文件系统扩展那步,或 xfs 卷误用了 resize2fs(会直接报错)。回到第三步按类型补做即可。
  • 云盘扩了但 pvresize 后没变化:PV 建在分区上(如 /dev/vdb1)时要先扩分区:sudo growpart /dev/vdb 1 再 pvresize /dev/vdb1;整盘 PV 才直接对设备 pvresize。
  • lvreduce 误操作缩过头:若文件系统还没被写坏且立刻发现,可尝试先把 LV 扩回原大小再 e2fsck 抢救;所以缩容前快照加备份这两道保险一个都别省。

小结

扩容记流程:加盘 → pvcreate → vgextend → lvextend → 按文件系统类型扩展(xfs 用 xfs_growfs 对挂载点,ext4 用 resize2fs 对设备)。缩容记铁律:xfs 不能缩、ext4 离线且先缩文件系统后缩卷。快照是临时回滚点不是备份,高风险操作前后都要用 df、lvs、vgs 三件套逐层验证。

发表回复

后才能评论