LVM2实战:从PV/VG/LV核心概念到在线扩容与快照管理
2026/9/18 5:46:16 网站建设 项目流程

我做过不少存储相关的运维和架构调整,说句实话,凡是跟分区打交道久了的人,迟早会遇到“磁盘空间不够用”“分区大小不能改”“扩容要停机”这类让人头疼的事。LVM2(Logical Volume Manager)这套逻辑卷管理方案,就是专门来解决这些麻烦的。你可以在不停机、不丢数据的前提下,把几个物理硬盘合并成一个大的存储池,再按需切分给不同服务;空间不够了,加一块新盘直接扩进卷组,再把某个逻辑卷撑大,几秒钟搞定,业务完全无感。这篇内容就是针对LVM2从概念到实战的完整梳理,包含我这些年操作下来的经验教训,以及那个“yum install 无效”的经典坑到底是怎么回事。无论你是刚接触Linux存储的新手,还是被现有分区方案限制住的老手,都可以照着做一遍。

1. 这套存储管理方案到底解决什么问题:从“分区定死”到“随时可变”

1.1 传统分区的痛点,你一定遇到过

传统的磁盘分区方案,一旦你用fdisk把/dev/sda1、/dev/sda2这些都划好,分区的大小就固定住了。后续如果根分区不够用,你想从相邻分区匀点空间过来,几乎要经历备份、删除分区、重建分区、再恢复数据这样的痛苦流程。要是这台机器是生产环境,这种操作基本等于宣布一段时间内服务不可用。

还有一种常见窘境:你有一块400G的盘和一个200G的盘,想给数据库目录弄个500G的空间,传统分区根本做不到这种“跨盘合并”的效果。你最多只能把两块盘各自挂成独立目录,然后手动做软链接或者搞分布式存储,但这类权宜之计往往给后续维护埋下大坑。

LVM2把物理磁盘抽象成资源池(卷组),再把池里的空间按需分给逻辑卷。从使用者的视角看,逻辑卷就是一个可以随时放大缩小的“分区”,但从底层视角看,它已经不受单块物理磁盘大小的限制。

1.2 LVM2在整个存储环节里处于什么位置

理解LVM2的位置很关键。Linux系统里数据落盘大致是这么一条链路:

  • 应用程序读写文件,走的是文件系统层,比如ext4、xfs。
  • 文件系统下面就是块设备层,传统情况下直接对应/dev/sda1这样的分区设备。
  • LVM2插在文件系统和物理磁盘之间,把物理分区或整块盘(PV)组合成VG,再切出LV。逻辑卷对文件系统而言就是一块普通块设备,所以ext4、xfs都能直接建在逻辑卷上。

有了这层抽象,你可以随时调整底层物理设备组合,而不影响上层文件系统已经看到的空间大小。也可以反过来,维持底层物理设备不变,动态扩展上层文件系统可用的空间。这种“双向解耦”就是LVM2的核心价值。

1.3 和其他方案横向对比,优势在哪里

拿LVM2和常见的RAID、普通分区来对比,各自的适用场景就很清楚了。

  • 普通分区:简单粗暴,适合固定场景,一旦部署后想调整空间非常麻烦。
  • RAID:主要解决的是性能和数据冗余问题。硬件RAID或mdadm软件RAID把多块盘组合成一个大设备,但它不提供灵活的容量切分能力。所以在实际生产里,RAID和LVM2经常会搭配使用——先用RAID把多块物理盘变成一个“大硬盘”,再在这个大硬盘上建LVM2来做空间切分。
  • LVM2:侧重的是容量灵活管理。它本身不替代RAID,RAID解决的是盘坏了不丢数据,LVM2解决的是空间不够了能随时扩。两者各司其职,可以完美组合。

LVM2还额外提供了快照功能,可以在极短时间内生成某个逻辑卷的“冻结副本”,备份数据库和文件系统时非常好用。虽然它不是备份软件的替代品,但作为备份前置手段,价值巨大。

2. 核心概念逐个拆解:PV、VG、LV、PE,一点都不玄乎

LVM2的整套体系里概念不算多,刚开始容易犯迷糊,但只要你抓住一条主线就全通了:把零散的物理存储(PV)汇集成一个大池子(VG),再从池子里抽出若干快小空间(LV)给系统用。

2.1 PV(Physical Volume,物理卷)是地基

PV是LVM2体系里的最小存储单元,一个PV通常对应一块物理磁盘上的一个分区(如/dev/sda1),也可以是一整块磁盘(/dev/sdb),甚至是一个RAID阵列设备。

把一块盘或分区初始化为PV,本质上是往这个设备头部写入LVM2的元数据区域,标记“这块空间由LVM2说了算”。一旦成为PV,这块盘就不再适合直接当普通分区挂载使用了,必须通过LVM2来管理。

这里有一个我踩过的坑:如果盘上已经格式化过且有数据,执行pvcreate之前务必备份数据,因为pvcreate会覆写设备头部元数据区域,旧文件系统信息就没了。

2.2 VG(Volume Group,卷组)是资源池

VG就是把所有PV整合后的“逻辑资源池”。你可以把它想象成一个蓄水池,PV就是汇入水池的管道,水池里的总容量就是各管道容量的总和。VGG给系统提供了一套统一调度的空间池,后续所有LV都从VG里划分。

VG里还有两个重要参数需要平时留意:

  • PE(Physical Extent,物理扩展块):VG分配空间的最小单位。创建VG时可以用-s参数指定PE大小,默认为4MB。这就像水池里的水是用桶来计的,每桶是统一标准。
  • 空闲空间:VG里未被LV占用的剩余空间,扩容LV时一般就是从这部分空间里调拨。

PE大小会影响后续LV操作的余量。如果PE太小,大容量VG在分配时元数据会稍多,而且扩展时要算的块数也更多;如果PE太大,比如1GB,那么创建一个小LV时可能就被凑整到1GB起步,浪费空间。综合考虑,大多数场景用默认的4MB就足够,只有超大容量存储池才建议调大。

2.3 LV(Logical Volume,逻辑卷)是最终交付给系统使用的部分

LV就是VG资源池上划分出来的“逻辑分区”。系统格式化时把它当成普通块设备来用,比如给根目录用的lv_root,给home目录用的lv_home。对文件系统来说,/dev/mapper/vg_name-lv_name或/dev/vg_name/lv_name就是一个普通设备,可以mkfs、mount,可以直接往上面读写数据。

LV可以用两种单位来创建:

  • 固定容量方式:-L 10G,直接指定逻辑卷大小。
  • PE数量方式:-l 100,意思是占用100个PE。如果PE为4MB,那么100个PE就等于400MB。

这两种方式在实际操作里都很常用,稍后实操部分会有具体例子。

2.4 数据是怎么从逻辑卷落到物理盘的

看到这里你可能好奇:LV和PV之间到底是怎么映射的?LVM2内部维护了一张映射表,把LV的每个区域映射到某个PV上连续的若干PE上。Linux内核通过device-mapper机制加载这张映射表,当系统读写LV时,实际I/O会被转发到对应的PV位置。

这张映射表的存在,就是LVM2能做在线扩容和迁移的底层基础。因为只要修改映射表,让新的区域指向新增的空闲PE,文件系统看到的空间就变大了,并不需要动已有数据的位置。快照功能也依赖这个机制:创建快照时不用拷贝全部数据,只需记录下“哪些区域的数据之后发生了变更”,读取快照时只要发现原区域数据有变,就取快照里保存的旧副本。

我以前给开发环境做快照时经常感叹,这个机制是真的巧妙,就像给一份文档做“增量备份”,每次只记录改动,而不是把整个文档重抄一遍。

3. 动手搭建一套LVM2环境:从安装到挂载的完整流程

3.1 那行yum命令为什么“无效”,这个坑必须说清楚

很多人第一次装LVM2时执行yum install -y lvm2,发现提示“Package lvm2-xxx already installed and latest version”,于是觉得“无效”,开始怀疑是不是命令没生效,其实完全不是这样。系统早就默认装了lvm2,因为很多基础组件都依赖它,它甚至不是可选的,而是系统存储栈的标配。

那“无效”这个热搜词的真正含义,往往是执行yum install -y yum-utils device-mapper-persistent-data lvm2这条整组命令时,其中某些包已经存在,或者某些包在特定版本源里找不到,导致系统提示大量“Nothing to do”或报错,看起来像“白执行了”。实际上device-mapper-persistent-data这个包是用来支持thin provisioning的,如果你的场景用不到精简配置,装不装它都不影响基础LVM2使用;yum-utils则是一套辅助工具,跟LVM2没有直接依赖关系。

如果你确实想确认LVM2是否可用,最直接的办法不是反复yum install,而是执行:

lvm version

或者

which lvcreate pvcreate vgcreate

如果这些命令能正常返回,说明环境里已经有完整的LVM2工具集了,压根不需要再装。

如果lvm命令确实缺失,比如在一台精简安装的容器镜像里,那么执行:

yum install -y lvm2

就会正常拉取并安装。装完之后再验证lvm version。要记住,yum里显示的“already installed”不是无效,而是“你已经有了”,这在Linux世界是一个好消息而不是错误。

3.2 磁盘准备:规划好之后再动手

我先准备三块新磁盘来演示,分别记为/dev/sdb、/dev/sdc、/dev/sdd。实际操作前先确认这些盘确实没有被系统占用,不然会造成数据损坏。

可以用lsblk查看:

lsblk

输出大概是这样的:

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 40G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 39G 0 part / sdb 8:16 0 20G 0 disk sdc 8:32 0 30G 0 disk sdd 8:48 0 50G 0 disk

我打算把它们全做成PV,汇合成一个100G的VG,然后从中划分LV。

如果某块盘上原来有分区表或者旧数据,用wipefs可以清理:

wipefs -a /dev/sdb

这条命令会把设备的文件系统签名和分区表签名都擦掉,避免后面pvcreate时出现“device not cleared”之类的提示。擦的时候一定要小心,确认盘符,千万别瞄准了系统盘。

3.3 创建PV、VG、LV:一行一行看效果

第一步,把三块盘都初始化为PV:

pvcreate /dev/sdb /dev/sdc /dev/sdd

执行后用pvs或pvdisplay查看状态。第一次做的时候看到三个PV整齐列出来,心里会特别踏实,因为这代表三块物理盘已经纳入了LVM2的管理范围。

第二步,创建一个名为vg_data的卷组,包含这三块盘:

vgcreate vg_data /dev/sdb /dev/sdc /dev/sdd

创建后可以用vgdisplay vg_data查看详情。VG的总容量正好是20+30+50=100G,空闲空间也是100G。

这里我一般会加上PE大小参数,虽然默认4MB就够用,但在演示或较大空间规划时,显式指定能让后续计算更清晰,比如:

vgcreate vg_data /dev/sdb /dev/sdc /dev/sdd -s 16M

把PE设为16MB后,后面按PE数量分配时,每一个PE就是16MB,计算起来很直观。

第三步,从vg_data里创建一个20G的逻辑卷,名字叫lv_data:

lvcreate -L 20G -n lv_data vg_data

也可以换用PE数量方式。如果PE采用16MB,2048除以16等于128,所以创建20G等价于128个PE:

lvcreate -l 128 -n lv_data vg_data

创建完成后,在/dev/mapper/目录下会多出一个vg_data-lv_data的链接,也可以写作/dev/vg_data/lv_data。此时逻辑卷已经可以当作块设备使用了,但还没有文件系统。

第四步,格式化并挂载。我习惯用ext4来演示,因为它在扩容缩容方面支持得更灵活。

mkfs.ext4 /dev/vg_data/lv_data mkdir -p /mnt/data mount /dev/vg_data/lv_data /mnt/data df -h

到这一步,一个20G的可用磁盘就出现在/mnt/data了。但它背后不是一个固定的分区,而是一个随时可以调节的逻辑卷,这就是LVM2的魅力。

3.4 开机自动挂载:别让业务重启后找不到盘

新挂载的设备不会自动在重启后生效,必须写入/etc/fstab。这里有一个细节值得注意:如果直接写/dev/vg_data/lv_data,虽然也能用,但设备名的解析在极端情况下可能出现问题。更稳妥的做法是用UUID或者/dev/mapper/下的稳定路径。

先通过blkid拿到逻辑卷的UUID:

blkid /dev/vg_data/lv_data

然后在/etc/fstab中追加一行(把UUID替换成你实际得到的值):

UUID=你的逻辑卷UUID /mnt/data ext4 defaults 0 0

添加后不要急着重启,可以先执行:

mount -a

如果这个命令没有报错,说明fstab配置记录没问题,重启后也能正常挂载。

注意:fstab一旦写错,可能导致系统开机进入emergency mode。所以写完fstab后一定先mount -a验证,这是避免翻车的最有效手段。

4. 日常最频繁的操作:逻辑卷在线扩容与缩减

4.1 在线扩容一个已经挂载的逻辑卷

这是LVM2最让人上瘾的功能。假设/mnt/data的lv_data现在20G,用着用着就满了。我想把它扩到30G,也就是增加10G。只要vg_data里还有空闲空间,就能在线完成,全程不需要卸载文件系统,也不影响正在写入的进程。

第一步,确认卷组剩余空间:

vgdisplay vg_data | grep Free

第二步,扩展逻辑卷。可以指定最终容量:

lvextend -L 30G /dev/vg_data/lv_data

也可以指定追加多少容量:

lvextend -L +10G /dev/vg_data/lv_data

在使用lvextend对已有数据的逻辑卷进行扩容时,务必加上--resizefs参数,让工具同时调整文件系统大小,一步到位。因为逻辑卷扩展后,文件系统并不会自动感知新增空间,不执行resize,新加的空间就用不上。

第三步,如果没加--resizefs,还需要手动适配文件系统:

resize2fs /dev/vg_data/lv_data

如果文件系统是xfs,则用:

xfs_growfs /mnt/data

注意,xfs不支持缩小,只能扩大,这算是个重要限制。

第四步,验证结果:

df -h

你会看到/mnt/data的容量已经从20G变成30G,而整个过程业务无感。我在生产上扩过不只一次数据库的存储卷,操作时应用日志还在哗哗地写,扩容完成后几乎没有任何中断,这种体验用起来很有安全感。

4.2 把空闲空间划给指定卷组:给资源池“加水”

如果整个vg_data的空闲空间都不够用了,就需要往卷组里新加入一块物理盘。比如我再加一块40G的盘/dev/sde,先初始化成PV,然后扩展卷组:

pvcreate /dev/sde vgextend vg_data /dev/sde

此时vg_data的容量从100G变成140G,空闲空间增加了40G。之后再次lvextend,就能把这40G也纳入某个逻辑卷。

这个过程里我最想强调的一个价值是:不用重启,不用迁移数据,不需要业务窗口,物理盘加进来后瞬间成为资源池的一部分。在云上你可能觉得分配磁盘点一下就行,但在裸金属机器上,这种“热添加”能力能省掉大量维护时间。

4.3 逻辑卷缩减:能做,但要把风险控制好

相比扩容,缩减操作风险更高,而且ext4支持缩减,xfs不支持。所以下面这个流程只适用于ext4或其他支持缩小的文件系统。

第一步,先检查文件系统:

e2fsck -f /dev/vg_data/lv_data

文件系统处于挂载状态时不要直接check,应先卸载:

umount /mnt/data

第二步,把文件系统从30G缩到25G:

resize2fs /dev/vg_data/lv_data 25G

这里注意顺序:永远先缩文件系统,再缩逻辑卷。如果顺序反了,逻辑卷已经缩到25G,文件系统还在30G,那文件系统尾部就会落到逻辑卷之外,数据损坏基本就是板上钉钉。

第三步,缩逻辑卷:

lvreduce -L 25G /dev/vg_data/lv_data

第四步,重新挂载:

mount /dev/vg_data/lv_data /mnt/data

实际操作时我很少在生产环境做缩减。因为缩减时间越长,窗口期越长,一旦断电或中途报错,数据完整性岌岌可危。能扩就不缩,这是存储运维的铁律之一。

5. 快照功能:备份数据前的“后悔药”

5.1 快照原理:不是拷贝整块卷,而是记录变更

LVM2快照最让人惊艳的是它的低开销原理。创建快照时,系统并不会把整个LV的数据复制一份,而是创建一个逻辑卷的“影子”——当原LV上有数据块即将被覆盖时,LVM2先把旧的数据块拷贝到快照区,再允许新写入。这样快照区里积累的就是“原卷中那些被修改之前的旧数据”,而未被修改的部分直接读取原卷即可。

所以快照的大小不需要等同于原LV,它只需要足够容纳“指定时间段内可能发生变更的数据量”。比如一个500G的数据卷,高峰期一小时内可能变更3G数据,那么你创建一个5G的快照就能撑住好几个小时。

5.2 实际操作:创建一个10G的快照卷

我先用lvcreate的-s参数创建快照:

lvcreate -L 10G -s -n lv_data_snap /dev/vg_data/lv_data

这里-L 10G表示快照数据的最大存储空间。创建后,可以把它挂载成一个只读副本,用于备份或数据比对:

mkdir -p /mnt/snap mount -o ro /dev/vg_data/lv_data_snap /mnt/snap

有了这个只读副本,你就可以用rsync、tar或数据库自带工具去跑备份,而不会和业务写入产生锁竞争。备份完成后卸载并删除快照:

umount /mnt/snap lvremove /dev/vg_data/lv_data_snap

如果发现快照空间被写满,快照会自动变为失效状态,无法继续使用,此时只能删除后重建。所以给快照规划容量时宁可多给一些,也不要太抠门。

5.3 快照的几个实际用途

除了备份前置,快照还能用于快速回滚。比如我升级数据库前先打一个快照,升级过程中如果出问题,直接把数据卷回滚到快照点即可。不过这里有另一种操作方式:为了绝对安全,可以先使用cp命令或rsync备份数据,这样即使快照被写满,手中也有完整的数据副本。

快照也可以用于搭建测试环境。比如给生产数据卷打个快照,然后把快照挂到一个测试机器或测试容器里,开发同学可以直接对真实数据做验证,不影响生产。这个用法在很多团队里特别受欢迎,大大减少了环境差异带来的诡异问题。

6. 常见问题与排查技巧实录

6.1 为什么lvm命令找不到

如果执行lvm version时报command not found,原因基本有两种:一种是系统确实没安装lvm2;另一种是极简容器镜像里只有基础工具链,LVM2相关命令没有被包含进去。解决方式:

yum install -y lvm2

或者对于Debian系:

apt-get install -y lvm2

安装完成后再次验证即可。要强调的还是那句:如果系统提示already installed,那不是“无效”,那是你的环境本来就有,你该做的是直接用,而不是反复安装。

6.2 创建PV时提示“Device /dev/sdb not found”

常见原因是设备名不对,或者磁盘在系统里还没被识别。可以用lsblk或fdisk -l确认盘符是否存在。如果设备确实存在但系统没刷新,可以执行:

partprobe

让内核重新读取分区表。如果是虚拟机里刚添加的磁盘,有时还需要重启或运行echo 1 > /sys/class/scsi_device/设备名/device/rescan来触发扫描。

6.3 pvcreate提示“device not cleared”

新磁盘或旧磁盘上存在文件系统签名、分区表残留时,LVM2出于安全考虑会拒绝直接初始化。解决办法就是wipefs -a清掉签名:

wipefs -a /dev/sdb

然后再pvcreate。清空前一定确认这块盘不要了,否则数据丢失就找不回来了。

6.4 卷组里明明有Free空间,lvextend却失败

一种情况是命令里目标参数写错了,比如忘了指定卷组名导致系统无法判断从哪个VG拿空间。另一种情况是VG有多个PV,且某些PV上的空闲空间处于碎片化状态,设备映射器无法一次性分配连续的物理extent。多数场景下LVM2自己会做空间整合,但如果仍然失败,可以先用pvs查看各PV的剩余空间,必要时用vgsplit或pvmove重新整理数据分布。

不过我得提醒一句:如果是严格的生产环境,不要为了省空间在根卷、home卷里来回腾挪,那是运维里最熬人的活之一。合理规划VG容量和PV数量,比事后补救要轻松得多。

6.5 开机进入emergency mode,大概率和fstab有关

之前写fstab如果写错,系统启动时找不到对应设备,就会掉进emergency mode。这时输入root密码进入系统后,执行:

mount -a

看哪一行报错,注释或修正fstab里的错误行,再执行:

systemctl daemon-reload reboot

根本性预防方案是:写新条目时用UUID或/dev/mapper/路径,并用mount -a验证后再重启。

6.6 逻辑卷无法删除,提示“Logical volume is in use”

这是因为逻辑卷正被挂载使用,系统不允许直接删除。先卸载所有挂载点,确认没有进程占用,再执行lvremove。有时候某些服务(如虚拟机热迁移、容器存储驱动)会长时间持有设备映射器的引用,导致即使umount也提示busy,这时就需要用lsof或fuser找到占用进程并处理掉。

我在实际排查里最高频的几类问题整理成一张表,方便平时速查:

现象原因解决方向
lvm命令不存在未安装lvm2yum/apt安装lvm2
pvcreate拒绝设备上有旧签名wipefs -a后重试
lvextend失败参数写错或空间碎片用vgs/pvs确认参数和空间
开机emergency modefstab写错mount -a查错并修正
lvremove提示in use卷被挂载或进程占用umount、找占用进程
快照失效快照空间被写满删除后重建更大快照

7. 一些我踩过多次才总结出来的经验心得

LVM2这东西,初看学起来不复杂,但真正用得顺手,需要在实际环境里反复打磨。我最想提醒你的是:不要把所有PV都堆在一个VG里,也不要把整个系统的所有LV都放在同一个VG里。分两个逻辑组会更安全,比如系统盘组单独一个VG,数据盘组单独一个VG。这样即使数据盘故障,系统卷还有机会单独恢复;反过来,系统盘出问题也不容易直接拖累数据卷。

另外,对于PE大小,我强烈建议在vgcreate时做好规划。默认4MB虽然没毛病,但如果你预计VG会达到数十TB,未来会创建大量小文件系统,不妨把PE提高到16MB或32MB。这样逻辑卷数量很多时,扩展时的统计数据会清爽得多。但如果你的场景是大量几个G级别的小逻辑卷,PE太大会造成空间浪费,默认4MB仍然是最稳妥的起点。

再有一个容易被忽视的点:LVM2和文件系统的扩容顺序必须记牢。逻辑卷扩容后如果文件系统没有同步扩大,你df看到的容量不会变化,这不是LVM2失效了,而是文件系统层没做resize操作。数据卷为ext4时用resize2fs,xfs时用xfs_growfs。xfs只支持扩大不支持缩小,所以对xfs卷千万别做lvreduce,一旦缩了基本等于自找麻烦。

备份这件事更要刻进肌肉记忆里。LVM2快照虽好用,但快照只在原卷的物理空间正常时才有意义。如果整块物理盘报废,快照也一起没了。真正的备份还要落到异机或对象存储里。快照适合做“时间点回滚”和“备份期间的数据一致性保障”,但它替代不了“备份”。

我自己的习惯是:对每一台服务器都建一个文本文档,记录VG、LV、PV的规划表,包括创建时间、扩容历史、快照操作记录。这个习惯救过我很多次,尤其是机器多了以后,靠记忆根本扛不住。配合lvmdiskscan、pvs、vgs、lvs这些只读命令定期巡检,能提前发现空间不足和PV故障隐患。

最后再分享一个我觉得很实用的小技巧:当你给数据库、容器镜像目录这类I/O密集场景创建逻辑卷时,可以让LV不占满整个VG,保留20%左右空闲空间。这20%平时看似浪费,但关键时刻能让你不做任何停服操作就完成一次紧急扩容,甚至能让你原地打一个足够大的快照。存储运维的核心不是等事情发生了再去救火,而是把未来半小时能遇到的风险,提前到过去五分钟就规避掉。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询