很多人收藏过各种“LVM命令大全”,但真正上手干活,光有命令列表根本不够。我做服务器运维这些年,被人问得最多的不是“怎么把LVM装上”,而是“我明明给磁盘扩容了,lvextend 也执行了,怎么 df -h 一点变化都没有”。问题基本都出在没搞清楚 LVM 的层级,以及忽略了“扩逻辑卷”和“扩文件系统”这两步必须分开做。
这篇文章不打算把所有命令都罗列一遍,而是顺着实际使用场景,把最常用的 LVM 命令按“查空间、扩磁盘、建卷、删卷、做快照、故障排查”串起来,每个命令说清楚为什么要这样执行、执行完要验证什么。适合刚接触 Linux 逻辑卷管理的运维新手,也适合已经会敲 lvextend 但偶尔被莫名其妙报错卡住的人。
1. 空间明明加给逻辑卷了,df -h 为什么还是老样子
1.1 用三层结构理解 PV、VG、LV,而不是硬背命令
先说 LVM 的体系,因为命令再多,最后都会落到这三层关系上:
- PV(Physical Volume):物理卷,通俗说就是一块真实磁盘或者磁盘分区,也可以是一个 RAID 设备、云硬盘。
- VG(Volume Group):卷组,相当于把多块 PV 放进一个“存储池”,不直接给用户用,只是中间容器。
- LV(Logical Volume):逻辑卷,从 VG 里切出来的“虚拟分区”,格式化后挂载给系统用。
文件系统跑在 LV 上面,LV 从 VG 里分空间,VG 又建立在 PV 之上。这个结构有点像你想扩充小区的停车位:LV 是划给你家楼下的车位,VG 是整个地库,PV 是真正浇筑出来的混凝土空间。你在 lvextend 时只是把“停车位”划得更大了一点,但如果不告诉物业把画线重新刷一下,外面的标识还是老样子,系统自然认为空间没变。
所以“df -h 没变化”这件事,绝大多数情况下不是操作失败,而是缺少了最后一步:文件系统扩容。命令按照数据方向拆分,应该是:
- 先把新磁盘加入系统,让内核能看到设备。
- 用 pvcreate 把磁盘变成 PV。
- 用 vgextend 把 PV 加入 VG,VG 的空闲空间变多。
- 用 lvextend 把 VG 空闲空间分配给某个 LV。
- 执行 xfs_growfs 或 resize2fs,让文件系统识别到新的容量。
1.2 pvs、vgs、lvs 三个简写命令,现场读法要练熟
LVM 自带两套查询命令:一套是简短版 pvs、vgs、lvs,输出一行一条,适合快速看状态;另一套是详细版 pvdisplay、vgdisplay、lvdisplay,会输出 PE 大小、VG UUID、LV 路径等完整信息。日常排查先敲简短版,需要看细节再敲 display。
vgs 是我敲得最多的命令,因为它直接展示当前卷组剩余空间:
bash复制vgs
输出里 VFree 这一列最有用,表示卷组里还有多少可用空间。如果我想给 root 逻辑卷扩容,但 vgs 显示 VFree 为 0,说明卷组里已经没有空间了,这时候要先加磁盘进 VG,而不是直接 lvextend。
快速查询时的常用组合:
- vgs 看卷组剩余空间,判断是否需要加盘。
- lvs 看逻辑卷当前容量和路径。
- pvs 看物理卷对应哪块设备,确认系统识别到的磁盘有没有被加入 LVM。
详细信息的命令一般用在故障排查和迁移场景:
bash复制pvdisplay
vgdisplay
lvdisplay
注意 display 输出的信息量和包含的字段更多,比如 vgdisplay 会显示 PE Size、Total PE、Free PE,这些在做精确扩容时非常关键。vgdisplay 也是网络热词里频繁出现的命令,很多人在 CentOS 上做 LVM 扩容时都要通过它确认卷组名和剩余 PE。
如果你觉得 pvs/vgs/lvs 简写输出看不懂,一个实用技巧是把每列对应关系记下来:
| 命令 | 关键列 | 现场判断逻辑 |
|---|---|---|
| pvs | PV、VG、PSize、PFree | PV 是否已经被加入 VG,该 PV 上还有多少空间没用 |
| vgs | VG、#PV、#LV、VFree | VG 还剩多少空间,能不能直接扩 LV |
| lvs | LV、VG、LSize | LV 当前多大,路径是否正确 |
把这三个命令当成日常工具而不是“出现问题才查”,你会发现后续所有扩容、删除、迁移操作都会少踩很多坑。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 完整的扩容链路:从新磁盘到文件系统认账
2.1 先让系统识别到新磁盘,再谈 pvcreate
很多人跑到 pvcreate 这一步才发现系统里根本没有 /dev/sdb。物理机或虚拟化平台加了一块新硬盘,不会像 U 盘那样每次都能自动刷新出来。如果 fdisk -l 或 lsblk 看不到新盘,可以先扫描 SCSI 总线:
bash复制echo "- - -" > /sys/class/scsi_host/host0/scan
echo "- - -" > /sys/class/scsi_host/host1/scan
echo "- - -" > /sys/class/scsi_host/host2/scan
不同环境的主机号不一定相同,可以把 host 目录下的目录都列出来,挨个扫一遍。这条命令本身不难,难的是扫完之后还要用 lsblk 确认设备出现过。
看到设备后,有两种路径:
- 整块磁盘直接做 PV,适合独享数据盘,例如 /dev/sdb。
- 先分区再在分区上建 PV,适合磁盘还需要参与其他规划的场合。
我个人的生产习惯是:独立的数据盘直接整块建 PV,比如 pvcreate /dev/sdb,没必要非得切成 /dev/sdb1。但如果企业规范要求分区,分区时记得把分区类型改成 LVM,用 fdisk 的话是 t 然后输入 8e,用 parted 则是 set 1 lvm on。改完之后执行 partprobe 让内核重新读取分区表。
2.2 扩容的第一步是扩 VG:vgextend 的意义
已经有新盘了,接下来要把它变成卷组资源池的一部分。先看当前卷组名:
bash复制vgs
假设卷组名叫 centos,新盘是 /dev/sdb,执行:
bash复制pvcreate /dev/sdb
vgextend centos /dev/sdb
vgextend 的意思是“把这块物理卷塞进指定卷组”。执行完再用 vgs 查看,VFree 会明显变大。这一步很多人不重视,直接跳过 vgextend 就跑去 lvextend,结果报错 “Volume group has insufficient free space”,这其实是正常提示,说明卷组里还没空间可用。
2.3 lvextend 里 -L 和 -l 的区别,绝不能搞混
到了给逻辑卷扩容的环节,命令变成:
bash复制lvextend -L +10G /dev/centos/root
这里的参数值得仔细讲:
- -L 后面跟容量大小,带单位比较直观。
- +10G 表示在现有基础上增加 10G。
- 如果不写加号,比如 lvextend -L 10G,那意思不是“加 10G”,而是“把逻辑卷最终大小调整成 10G”。这个区别相当致命,生产环境里有人把 +号漏掉,结果 LV 被直接缩小,后果非常严重。
-l 参数则是用 PE 数量或百分比表示,常见用法有:
bash复制lvextend -l +100%FREE /dev/centos/root
这条命令把卷组剩余空闲全部加到 root 逻辑卷里。注意,如果卷组里还有其他逻辑卷需要留空间,不要随手用 100%FREE,否则会一次性把空间吃干。指定某个 LV 只拿一半空闲可以写成:
bash复制lvextend -l +50%FREE /dev/centos/root
关于 PE 大小,vgdisplay 会显示 PE Size,默认多为 4MiB。假设 PE Size 是 4MiB,给 LV 增加 255 个 PE,实际增量是 1020MiB,不是 255MiB。看到这种差异不要慌,算一遍 PE Size 乘以 PE 数才准确。
2.4 文件系统扩容:xfs_growfs 和 resize2fs 按类型选
lvextend 执行完,如果用 lvs 看 LV 大小,会发现逻辑卷已经变大。但 df -h 还是原来的值,因为文件系统没有感知。这时必须根据文件系统类型执行对应命令。
先用 blkid 确认逻辑卷上的文件系统类型:
bash复制blkid /dev/centos/root
如果是 CentOS 7/8 默认的 XFS,使用:
bash复制xfs_growfs /
注意 xfs_growfs 后面跟的是挂载点,不是设备路径。如果是根分区,直接写 / 即可;如果是 /data,则写 /data。XFS 支持在线扩容,不需要卸载文件系统。
如果是 ext4,使用 resize2fs:
bash复制resize2fs /dev/centos/root
resize2fs 后面跟设备路径,也就是 /dev/mapper/xxx 或 /dev/卷组名/逻辑卷名。ext4 同样支持在线扩容。
有些文章会推荐 lvextend -r 一步到位,让命令自动调用文件系统扩容工具。这个参数在某些发行版和较新版本上确实可用,但我的建议是如果服务器环境比较老,或者你对当前文件系统类型没有十足把握,还是分开执行更稳妥。因为一旦 -r 内部匹配错误,它可能会拿 resize2fs 去处理 XFS,那就会浪费时间排查了。
验证扩容结果:
bash复制df -h
lvs
vgs
df -h 对应文件系统视角,lvs 对应逻辑卷视角,vgs 对应卷组资源池视角。三个输出都正常,才算整个链路成功。
3. 创建、删除、改名与维护:顺序比命令本身更重要
3.1 从零创建一个 LVM 数据卷的标准操作
假设新机器上有一块 500G 的数据盘 /dev/sdb,需要做一个 400G 的逻辑卷挂到 /data,一套完整步骤如下:
bash复制# 1. 把整块盘变成 PV
pvcreate /dev/sdb
# 2. 创建卷组
vgcreate data_vg /dev/sdb
# 3. 创建逻辑卷
lvcreate -n data_lv -L 400G data_vg
# 4. 格式化
mkfs.xfs /dev/data_vg/data_lv
# 5. 挂载
mkdir -p /data
mount /dev/data_vg/data_lv /data
命令看起来很简单,但有几个细节经验值得写下来。
lvcreate 的 -n 是逻辑卷名,-L 是容量。如果你有多个 PV,可以在 vgcreate 后面一次性接多个设备;也可以之后用 vgextend 添加。格式化之前务必确认逻辑卷路径正确,mkfs 是破坏性操作,一旦跑错设备,数据就没了。
写入 /etc/fstab 时,建议用 UUID 而不是 /dev/data_vg/data_lv 这种设备路径。因为一旦逻辑卷被删除重建,设备路径可能不变,但文件系统 UUID 会变化,通过 UUID 挂载更利于排查问题。获取 UUID 用 blkid:
bash复制blkid /dev/data_vg/data_lv
3.2 删除卷的硬性顺序:lvremove、vgremove、pvremove 不能乱
删除 LVM 逻辑卷是高风险操作,越是有经验的人越会先执行一遍 lsblk、lvs、df -h,确认没有进程占用。
完整删除一个数据卷的顺序是:
bash复制# 1. 卸载挂载点,如果有服务在写,先停服务
umount /data
# 2. 删除逻辑卷
lvremove /dev/data_vg/data_lv
# 3. 删除卷组
vgremove data_vg
# 4. 删除物理卷标记
pvremove /dev/sdb
这种顺序的逻辑在于:必须先删除文件系统所在的 LV,卷组才能被释放;卷组不存在了,PV 上的 LVM 元数据标记才允许被清除。如果你在还有 LV 的情况下强行 vgremove,系统会提示卷组仍在使用,并拒绝执行。
删除物理卷从卷组中“踢出去”则是另一套思路。假设卷组 data_vg 里有两块盘 /dev/sdb 和 /dev/sdc,现在想把 /dev/sdc 下线换掉,需要先把它的数据迁移走:
bash复制pvmove /dev/sdc
vgreduce data_vg /dev/sdc
pvremove /dev/sdc
pvmove 会把该 PV 上的数据挪到卷组内其他空闲 PV 上,执行完后数据不会再占用这块盘,vgreduce 才能安全移除 PV 身份。这个链路里的原因是:如果直接 vgreduce 把还在承载数据的 PV 从卷组里移除,数据对应的逻辑卷就会缺少底层 extent,结果不是报错就是数据不可读。顺序错一步,代价都很大。
3.3 逻辑卷改名和卷组改名,注意挂载关系的连锁反应
改名字包括 lvrename 和 vgrename,例如:
bash复制lvrename data_vg/data_lv data_old
vgrename data_vg data_pool
改名本身不复杂,复杂的是会影响挂载配置。如果 /etc/fstab 里写的是 /dev/data_vg/data_lv,改完卷组名或逻辑卷名后,设备路径随之变化,重启后系统可能找不到原来的卷,启动时进入紧急模式。
如果使用 UUID 挂载,改名反而影响不大,因为文件系统 UUID 没有变。这一点再次说明,生产环境 fstab 用 UUID 会省掉不少风险。
3.4 关于缩容:一条必须记住的安全提示
LVM 并不是只能扩容,也可以缩容,但缩容的坑比扩容多得多。
- XFS 文件系统不支持缩容。
- ext4 虽然支持缩小,但缩容必须在文件系统卸载状态下进行,且操作时要先收缩文件系统,再缩小 LV,顺序反过来会导致数据损坏。
我不建议在生产环境做在线缩容实验。如果磁盘空间分配过多,常规做法是检查是不是有历史日志或者大文件占着空间,而不是贸然把 LV 缩小。缩容需要先把文件系统缩小,而一旦文件系统缩小过程异常,恢复数据要比扩容难得多。保留“能用扩容解决的尽量别碰缩容”这个意识,是运维保命的底线之一。
4. 快照与迁移:把 LVM 的“后悔药”吃明白
4.1 lvcreate -s 创建快照,备份前的一致性思路
LVM 快照是我在给数据库服务器做变更前最常用的保护手段之一。创建一个快照的命令:
bash复制lvcreate -L 20G -s -n snap_before_change /dev/data_vg/data_lv
参数含义:
- -s 表示 snapshot,即快照。
- -n snap_before_change 是给快照起名。
- 后面的设备路径是你要快照的源逻辑卷。
快照背后的原理是写时复制(Copy-On-Write)。它不会一开始就把 20G 数据全部复制,而是先标记“我拍了快照”,当源逻辑卷后续有数据块被修改时,系统会把修改前的旧数据先写入快照空间。所以快照刚创建时占用很小,但源卷改动越多,快照占用的空间越大。
给快照分配多大空间合适?取决于变更窗口内源卷会有多少数据被修改。如果是每天变化量很大的数据库,给 10% 到 30% 都不一定够;如果只是停机做一个配置变更,给 10G 到 20G 通常够用。快照空间不足时,快照会自动失效,变成不可用状态,在逻辑卷列表里会显示为悬挂状态,恢复可能性很低。因此创建快照后,时不时用 lvs 看快照使用率,不要让它默默爆掉。
4.2 不要把 LVM 快照当成数据库一致性的唯一保证
很多新人以为有了 LVM 快照,数据库备份就万事大吉。实际上,LVM 快照是设备层的一致性,它保证的是文件系统层面的“某个时间点”,但数据库引擎在内存里可能还有未落盘的事务日志。直接把快照挂载出来拷贝数据文件,得到的数据库状态不一定能顺利恢复。
我常用的做法是:先让数据库执行自己的备份命令或处于一致性状态,再做 LVM 快照。比如 MySQL 可以用 mysqldump 或 xtrabackup 完成逻辑一致后,再在较低负载窗口打快照;PostgreSQL 则考虑 pg_basebackup。LVM 快照最大的价值是给变更前留一个回滚点,变更出问题后可以快速挂载快照找到旧数据,而不是替代数据库自身的备份机制。
4.3 pvmove 把数据从可疑盘移走,配合 vgreduce 下线
前面提过 pvmove 是用在删除 PV 之前的迁移工具,这里展开说。假设卷组 data_vg 由 /dev/sdb 和 /dev/sdc 组成,现在 /dev/sdb 出现大量 I/O 错误或者需要硬件下线,执行:
bash复制pvmove /dev/sdb
pvmove 会把 /dev/sdb 上承载的所有逻辑卷数据搬到同卷组其他空闲 PV 上,也就是 /dev/sdc 的空闲区域。如果卷组本身没有多余空间,则必须先加新盘并 vgextend:
bash复制pvcreate /dev/sdd
vgextend data_vg /dev/sdd
pvmove /dev/sdb
pvmove 根据数据量大小可能耗时较长,并且会占用磁盘 I/O,最好在业务低谷执行。执行期间可以用单独终端看进度:
bash复制pvmove -i 5
数据迁移完成后,再做 vgreduce data_vg /dev/sdb 和 pvremove /dev/sdb,这时把这块盘拔掉才安全。
4.4 vgexport 和 vgimport 是跨主机迁移老服务器的利器
整机迁移场景中,把整个 LVM 卷组从旧机器搬到新机器,命令链路并不长,但每一步都有强制性前提。先看旧机器上的操作:
bash复制vgchange -an data_vg
vgexport data_vg
vgchange -an 的作用是把卷组标记为不活跃,并停止内核访问。vgexport 再把卷组标记为“已导出”。很多教程只让你执行 vgexport,却没强调先执行 vgchange -an,结果到新机器上导入时总提示卷组状态不对。
做完这两步,关机拔盘,把磁盘装到新机器上。新机器执行:
bash复制pvscan
vgscan
vgimport data_vg
vgchange -ay data_vg
mount /dev/data_vg/data_lv /data
vgimport 让新系统接管卷组元数据,vgchange -ay 把卷组激活。如果新机器上已经有一个同名卷组,导入前先重命名本地卷组,避免冲突。
这套流程对我来说最大的价值是:不用重新配置业务、不用重新拷贝数据,只需搬物理盘或虚拟磁盘,整个卷组的逻辑结构都能原样带过去。
5. 重启后 LV 不见了?用这套链路判断问题出在哪一层
5.1 现象:重启后挂载点丢失,/dev/mapper 下也没有逻辑卷
服务器重启后出现文件系统找不到,是比较吓人的故障。看到 /etc/fstab 里配置的挂载路径不存在时,不要立刻执行格式化、重建卷之类的动作。先按照 PV、VG、LV 从底往上的顺序排查,确定是物理盘没识别出来,还是卷组没有激活,又或者是逻辑卷本身就损坏了。
排查的第一步是看物理卷:
bash复制pvscan
如果 pvscan 能找到 PV,并提示属于某个卷组,说明底层磁盘和 LVM 元数据都还在。如果 pvscan 看不到任何 PV,问题可能出在磁盘驱动、多路径软件或硬件识别层,这时候 LVM 层面做不了太多事,先检查 dmesg 和磁盘设备是否在 lsblk 中可见。
第二步是扫描卷组:
bash复制vgscan
vgdisplay
如果 vgdisplay 显示 Status 为 NOT available,说明卷组没有被激活。很多迁移或未配置自动激活的系统重启后就会处于这个状态。此时执行:
bash复制vgchange -ay data_vg
激活后再看 /dev/mapper 下是否出现对应设备,并重新挂载。要注意,如果是集群环境,还要确认卷组没有在其他节点被占用,强制激活会导致数据损坏。
5.2 unknown device 和元数据恢复的急救思路
有一种常见情况是,某块 PV 因为磁盘故障或者其他原因在系统中变成 unknown device,导致 VG 无法正常激活。pvscan 输出里会出现类似 “unknown device” 的提示。这时不要急着 vgreduce --removemissing,因为这个命令会把缺失 PV 上对应的数据 extent 也一并移除,相当于直接把那部分数据标记为不可用。
正确思路是先判断缺失 PV 上的数据是否能从其他途径找回。如果只是设备路径变化,可以通过 multipath 工具或重新连接磁盘让 PV 重新出现;如果那块 PV 已经彻底损坏,且有备份,再考虑后续修复手段。
LVM 还有个重要的元数据备份目录 /etc/lvm/backup,里面保存了卷组曾经的配置信息。如果出现卷组元数据丢失或损坏,可以用 vgcfgrestore 尝试恢复卷组定义:
bash复制vgcfgrestore data_vg --file /etc/lvm/backup/data_vg
前提是底层 PV 的结构没有被改动,否则恢复后可能对不上实际数据布局。这个命令的适用边界比较窄,不建议在不理解原理的情况下随意尝试。总之,遇到 LVM 卷组消失,先 pvscan、vgscan、vgdisplay 把状态看全,再决定激活、导入还是恢复,不要一上来就重建。
5.3 隐藏参数带来的挂载坑:逻辑卷没有自动激活
有些系统重启后 VG 状态是 available,但对应 LV 并没有自动激活,挂载 fstab 时就会失败。这时用 lvscan 看逻辑卷状态:
bash复制lvscan
如果逻辑卷显示 inactive,可以用 lvchange 单独激活:
bash复制lvchange -ay /dev/data_vg/data_lv
激活后再 mount。这种情况多见于手动导入的卷组或从其他机器迁移过来的卷组,系统没有把它加入 auto activation 列表。遇到类似问题,不要反复重启,先手动激活比什么都管用。
6. 常用场景命令速查表
操作类命令不用天天敲,但每次敲完都应该清楚下一步是什么。我整理了一份按场景拆分的速查表,方便在服务器前快速对照。
| 场景 | 命令链路 | 关键提醒 |
|---|---|---|
| 查看当前空间 | df -h、lvs、vgs | 三层都要看,只看 df 会漏判文件系统未扩容 |
| 新盘加入卷组 | lsblk、pvcreate、vgextend | 扫描不到磁盘先 echo scan SCSI |
| 逻辑卷扩容 | lvextend、xfs_growfs / resize2fs | 先扩 LV,再扩文件系统,别弄反 |
| 新建数据卷 | pvcreate、vgcreate、lvcreate、mkfs | 确认卷组名和逻辑卷路径 |
| 删除整组卷 | umount、lvremove、vgremove、pvremove | 有进程占用时先停服务,严格按顺序删 |
| 下线单块 PV | pvmove、vgreduce、pvremove | 数据迁移完成前禁止 vgreduce |
| 变更前保护 | lvcreate -s 创建快照 | 关注快照使用率,防止空间耗尽失效 |
| 整机迁移卷组 | vgchange -an、vgexport、vgimport、vgchange -ay | 新机器导入前处理卷组重名 |
| 重启后卷组不激活 | pvscan、vgscan、vgchange -ay | 不要急着 vgreduce --removemissing |
我后来养成了一个习惯:不管操作多熟练,动手之前固定敲三下命令,df -h 确认当前文件系统使用率,lvs 看逻辑卷路径,vgs 看卷组剩余空间。这三下能把当前机器的存储关系快速对齐,也能避免很多“复制粘贴导致删错设备”的低级事故。
LVM 命令本身并不复杂,真正复杂的是理解每一步操作背后的层级关系。把“查空间、扩空间、删卷、快照、迁移、恢复”这几个场景练熟,再遇到大部分磁盘相关问题,你都不会慌。毕竟在 Linux 存储运维里,规划和顺序永远比敲命令的速度更重要。
