Linux LVM 逻辑卷管理实战:创建、在线扩容与数据迁移完整指南

很多个人站长都遇到过这样的场景:服务器磁盘快满了,网站还能正常跑,但数据库备份脚本一执行就报错,日志写不进去,后台操作卡顿。查看磁盘的时候才发现根分区或者数据分区只剩几个 G,而当初分区时预留的空间早已用完。如果当初用的是传统分区方案,这时候要么加一块新硬盘重新挂载、迁移数据,要么找服务商重装系统,费时费力还有数据风险。

如果你在装系统时用了 LVM 逻辑卷管理,情况就完全不一样。LVM 可以在线扩容,不需要停机,不需要迁移数据,甚至可以把多块物理硬盘合并成一个逻辑卷来用。本文从概念讲起,把创建、扩容、缩容、快照和故障排查完整走一遍,所有命令都直接可用,建议收藏后照着操作。

一、LVM 到底解决了什么问题

传统分区方案里,一块硬盘分几个区,每个区大小固定,扩容非常麻烦。LVM(Logical Volume Manager,逻辑卷管理)把物理磁盘抽象成三层结构:物理卷(PV)、卷组(VG)和逻辑卷(LV),相当于在磁盘和文件系统之间加了一层"弹性池"。

  • 物理卷 PV(Physical Volume):把一块硬盘或一个分区初始化成 LVM 可用的存储单元,对应命令 pvcreate
  • 卷组 VG(Volume Group):一个或多个 PV 组成的存储池,池子里的空间统一分配,对应命令 vgcreate
  • 逻辑卷 LV(Logical Volume):从 VG 里划出来的逻辑分区,格式化后挂载使用,对应命令 lvcreate

最小的存储单位叫 PE(Physical Extent),默认 4MB,所有空间分配都以 PE 为粒度。理解这三层关系,后面的操作就顺理成章了:给 VG 加 PV 是扩容池子,给 LV 加空间是从池子里多划一些出来。

二、从零创建 LVM:把一块新硬盘变成逻辑卷

假设服务器加了一块 200G 的新硬盘 /dev/sdb,目标是把它做成一个挂载在 /data 的逻辑卷。第一步先分区并设置分区类型为 LVM(8e):

fdisk /dev/sdb
# 依次输入:n(新建分区)→ p(主分区)→ 回车(默认分区号)→ 回车(默认起始扇区)→ 回车(默认结束扇区)→ t(改类型)→ 8e(Linux LVM)→ w(保存)
partprobe /dev/sdb   # 让内核重新读取分区表

也可以跳过分区直接用整块盘,但建议保留分区,方便以后调整。接下来初始化 PV、创建 VG、创建 LV 并格式化挂载:

pvcreate /dev/sdb1
vgcreate vgdata /dev/sdb1
lvcreate -L 180G -n lvdata vgdata
mkfs.ext4 /dev/vgdata/lvdata
mkdir -p /data
mount /dev/vgdata/lvdata /data
echo "/dev/vgdata/lvdata /data ext4 defaults 0 2" >> /etc/fstab

其中 -L 180G 指逻辑卷大小,-n lvdata 是逻辑卷名字,vgdata 是卷组名。挂载信息写进 /etc/fstab 后重启也能自动挂载。执行完用 df -hlvs 验证,能看到 /data 挂载了 180G 的空间。

三、在线扩容:磁盘不够了怎么办

这是 LVM 最常用的场景。网站跑了一年,/data 快满了,不需要停机,直接在线扩容。分两步:先用 lvextend 扩大逻辑卷,再调整文件系统大小。ext4 和 xfs 的第二步命令不一样:

# 1. 把逻辑卷扩大 50G
lvextend -L +50G /dev/vgdata/lvdata

# 2a. ext4 文件系统:resize2fs 在线调整
resize2fs /dev/vgdata/lvdata

# 2b. xfs 文件系统:xfs_growfs 必须指定挂载点
xfs_growfs /data

两个常用变体:lvextend -L 250G /dev/vgdata/lvdata 是把逻辑卷直接扩到 250G(绝对值),-l +100%FREE 是把卷组剩余空间全部给逻辑卷,适合"有多少加多少"的场景:

lvextend -l +100%FREE /dev/vgdata/lvdata
resize2fs /dev/vgdata/lvdata

整个过程网站服务完全不受影响,数据不会丢。扩容后记得用 df -h 确认文件系统确实变大了——只扩 LV 忘了 resize 文件系统是新手最常见的错误。

四、缩容:需要谨慎操作的操作

LVM 支持缩容,但必须牢记两条铁律:必须先缩小文件系统,再缩小逻辑卷,顺序反了会直接损坏数据;xfs 文件系统不支持缩容,只能扩不能缩。ext4 缩容步骤:

# 1. 先卸载分区(ext4 在线缩容风险高,建议离线操作)
umount /data
# 2. 强制检查文件系统
e2fsck -f /dev/vgdata/lvdata
# 3. 先把文件系统缩到目标大小(务必留余量,先缩文件系统)
resize2fs /dev/vgdata/lvdata 200G
# 4. 再缩逻辑卷
lvreduce -L 200G /dev/vgdata/lvdata
# 5. 重新挂载
mount /dev/vgdata/lvdata /data

缩容前务必做好备份,缩容过程中断电、误操作都可能导致数据丢失。生产环境如果不是特别必要,一般不建议缩容。

五、卷组扩容:一块盘不够就再加一块

这是 LVM 比传统分区强得多的杀手锏:VG 空间不够时,直接加一块新盘并扩展进卷组,LV 就能继续扩容,多块盘对上层完全透明。假设新加了 /dev/sdc

fdisk /dev/sdc    # 同样新建分区并设为 8e
partprobe /dev/sdc
pvcreate /dev/sdc1
vgextend vgdata /dev/sdc1
# 查看卷组和物理卷状态
vgs
pvs

之后照常 lvextend 即可。如果两块盘性能差异大,还可以用 pvmove 把数据从一块盘迁移到另一块,实现在线更换硬盘:

pvmove /dev/sdb1 /dev/sdc1   # 把 sdb1 上的数据迁移到 sdc1
vgreduce vgdata /dev/sdb1    # 从卷组中移除 sdb1
pvremove /dev/sdb1           # 移除 PV 标记,可以拔盘了

六、LVM 快照:低成本的备份利器

LVM 快照可以在秒级生成一个逻辑卷的"时间点副本",做数据库备份前先打快照,再挂载快照做备份,可以避免备份过程中的数据不一致:

# 为 lvdata 创建一个 10G 的快照
lvcreate -s -L 10G -n lvdata_snap /dev/vgdata/lvdata
# 挂载快照(只读)读取数据
mkdir -p /mnt/snap
mount -o ro /dev/vgdata/lvdata_snap /mnt/snap
# 备份完成后卸载并删除快照
umount /mnt/snap
lvremove /dev/vgdata/lvdata_snap

快照大小不用等于原卷大小,它只记录变化的数据块,但快照写满后会失效,所以给足余量,用完及时删除。

七、云盘扩容场景:pvresize 让 PV 识别新大小

现在大多数站长用的是云服务器,这里单独说一个云环境特有的高频操作。云盘(数据盘)在控制台扩容后,登录服务器会发现容量没变——因为 PV 记录的还是旧大小。此时需要用 pvresize 让 LVM 重新扫描物理卷的容量:

pvresize /dev/vdb1
# 查看扩容后的卷组可用空间
vgs
# 然后照常扩逻辑卷和文件系统
lvextend -l +100%FREE /dev/vgdata/lvdata
resize2fs /dev/vgdata/lvdata

这是云服务器上最常见的 LVM 扩容路径:控制台扩云盘 → pvresizelvextendresize2fs/xfs_growfs,全程在线,业务不中断。如果执行 pvresize 后 vgs 里 VFree 没有变化,先确认云盘在系统里的设备名没变(扩容后设备名一般不变),再用 lsblk 对比磁盘实际大小。

八、常见故障排查

LVM 出了问题不要慌,三个扫描命令先跑一遍:pvscanvgscanlvscan,它们会显示当前系统里能识别到的 PV、VG、LV 状态。常见问题及处理:

  • 开机提示找不到卷组:通常是系统启动顺序问题,在引导配置里加 rd.lvm.lv=vgdata/lvdata 内核参数,或确认 LVM 相关服务(如 lvm2-lvmetadlvm2-activation)已启用。
  • vg 显示 inactive:执行 vgchange -ay vgdata 激活卷组。
  • PV 丢失导致卷组不完整:用 vgcfgrestore 从备份恢复卷组元数据,或检查是不是换了盘符,pvscan 会提示原 PV 的 UUID,可用 pvcreate --uuid 找回原标记。
  • 误删逻辑卷:如果 vg 里还有空间且未写入新数据,可尝试 vgcfgrestore 配合 lvchange -ay 找回,但最可靠的办法还是平时的备份。

九、常用查看与统计命令

运维 LVM 离不开查看命令。三个简写命令最常用:pvs 看物理卷、vgs 看卷组、lvs 看逻辑卷,输出简洁,适合日常巡检。以 vgs 为例:VG 是卷组名,#PV 是卷组里的物理卷数量,#LV 是逻辑卷数量,VSize 是卷组总容量,VFree 是剩余可用空间——扩容前先看 VFree,如果为 0,说明要先 vgextend 加盘。pvs 关注 PSize(物理卷大小)和 PFree(该盘剩余空间);lvs 关注 LSize(逻辑卷大小)和 Data%(数据占用比例)。需要看详细信息时用 pvdisplayvgdisplaylvdisplay,会输出 PV 的 UUID、PE 大小、LV 路径等,排错时经常要用。

还可以把巡检写成脚本配合定时任务,卷组快满时自动告警:

#!/bin/bash
# /usr/local/bin/check_vg.sh
VG="vgdata"
WARN=20   # 剩余低于 20G 告警
FREE=$(vgs --noheadings -o vg_free --units g $VG | awk '{print int($1)}')
if [ "$FREE" -lt "$WARN" ]; then
    echo "警告: 卷组 $VG 剩余空间仅 ${FREE}G" | mail -s "磁盘空间告警" you@example.com
fi

最后提醒一点:LVM 把多块盘合成一个卷组后,数据会分散在不同物理盘上,IO 性能是叠加的,但单块盘故障的风险也随之而来——卷组里任何一块盘坏了,整个卷组都可能无法访问。所以生产环境建议底层用 RAID 或云盘快照兜底,LVM 解决的是"容量弹性"问题,数据冗余还是要靠 RAID 和备份策略。

总结

LVM 是 Linux 服务器上性价比极高的"后悔药":磁盘不够在线扩,硬盘坏了热迁移,备份前打快照,云盘扩容一条命令搞定。新装系统时把数据分区做成 LVM,或者把闲置盘转成 LVM 卷组,以后会省下大量折腾时间。建议实际操作时先在测试机上完整演练一遍创建、扩容、缩容流程,熟悉后再上生产环境,并且养成扩容前 df -hvgslvs 三连检查的习惯。

Last modification:August 11th, 2026 at 08:37 am

Leave a Comment