1. 为什么你需要掌握LVM?从“硬盘分区”到“存储池”的思维跃迁
大家好,我是老张,在运维和存储这块摸爬滚打了十几年。今天我们不聊那些虚头巴脑的理论,就来手把手、接地气地聊聊LVM(逻辑卷管理)的实战操作。如果你还在为服务器加硬盘、分区、迁移数据搞得焦头烂额,觉得每次调整存储空间都像在做一次高风险手术,那LVM可能就是你的“解药”。
想象一下这个场景:你负责的网站业务量增长,/data目录眼看就要满了。传统的做法是,加一块新硬盘,分区、格式化,然后把旧数据吭哧吭哧挪过去,改挂载点,还得调整应用配置,整个过程服务得停,心惊胆战。但如果你用了LVM,情况就完全不同了:你只需要把新硬盘“加入”到原有的存储池里,然后在线、动态地给/data“扩大”空间,整个过程业务无感知,就像给一个水池加注水一样简单流畅。
LVM的核心思想,就是把物理硬盘(或分区)抽象成可以灵活拼装的“积木”。它主要管理三个层次:物理卷(PV)、卷组(VG)和逻辑卷(LV)。你可以把多块物理硬盘(PV)揉成一个大的“存储池”(VG),然后从这个池子里,按需切分出任意大小的“逻辑磁盘”(LV)给系统使用。这个逻辑卷才是我们最终格式化并挂载的“分区”。它的魔力在于,这个“逻辑磁盘”的大小可以动态调整,不再受底层物理硬盘边界的束缚。
所以,无论你是刚入行的运维新人,还是需要管理自家NAS的极客,花点时间掌握LVM,绝对是提升效率、保障数据灵活性的高回报投资。接下来,我们就从最基础的创建开始,一步步走到高级的扩容和风险较高的缩容操作,我会把每个命令背后的“所以然”和踩过的坑都讲清楚。
2. 万丈高楼平地起:物理卷、卷组与逻辑卷的创建
别被那些术语吓到,我们一步步来。你可以把创建LVM的过程,想象成盖房子:先准备砖头(PV),再用砖头砌成一面完整的墙(VG),最后根据房间布局,在这面墙上开出窗户和门(LV)。
2.1 准备“砖头”:使用 pvcreate 创建物理卷
物理卷(PV)是LVM的基石,它可以是整块硬盘(如/dev/sdb),也可以是硬盘上的一个分区(如/dev/sdb1)。但请注意,我强烈建议直接使用整块硬盘作为PV。为什么呢?因为分区本身就有大小限制,如果你先用分区,后期想扩容还得折腾分区表,徒增复杂度。直接用整盘,让LVM来管理空间,是最干净利落的做法。
假设我们有两块新硬盘/dev/sdb和/dev/sdc,准备纳入LVM体系。创建物理卷的命令简单到令人发指:
[root@server ~]# pvcreate /dev/sdb /dev/sdc
Physical volume "/dev/sdb" successfully created.
Physical volume "/dev/sdc" successfully created.
执行完,这两块盘就被打上了LVM的“烙印”,准备被使用了。怎么确认呢?用pvs或pvdisplay命令查看一下:
[root@server ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb lvm2 --- 8.00g 8.00g
/dev/sdc lvm2 --- 6.00g 6.00g
pvs是简洁视图,可以看到PV名称、所属卷组(VG,目前为空)、格式、属性、总大小和剩余空间。pvdisplay则会给出极其详细的信息,包括UUID、PE大小等,在排查复杂问题时特别有用。这里有个小细节:Attr字段下的---表示这块PV尚未加入任何卷组。创建PV本身不会损坏原有数据,但如果你在已使用的分区上执行,一定要先备份!
2.2 砌成“墙”:使用 vgcreate 创建卷组
有了砖头(PV),我们就可以把它们组合起来,砌成一堵大墙,也就是卷组(VG)。卷组是LVM的核心概念,它是一个真正的存储池,所有后续的逻辑卷都从这个池子里分配空间。
我们把刚才创建的两块PV,/dev/sdb(8G)和/dev/sdc(6G),合并成一个名为vg_data的卷组:
[root@server ~]# vgcreate vg_data /dev/sdb /dev/sdc
Volume group "vg_data" successfully created
这个命令执行后,这两块物理盘的空间就被聚合成了一个总计约14G的存储池。这里有个重要的概念叫PE(Physical Extent),你可以把它理解为存储池管理空间的最小单元,就像砌墙用的标准砖块。默认PE大小是4MB。在创建卷组时,你可以通过-s参数指定PE大小,比如-s 8M或-s 16M。对于特别大的存储(TB级别),设置更大的PE(如32M、64M)可以减少管理元数据的开销,但可能会造成微小的空间浪费。对于大多数场景,默认的4MB就非常合适。
创建成功后,用vgs或vgdisplay查看一下:
[root@server ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vg_data 2 0 0 wz--n- 13.99g 13.99g
可以看到,卷组vg_data包含2个PV,0个LV,总大小13.99G(因为二进制换算和少量元数据占用,会比14G略小),所有空间目前都是空闲(VFree)的。这堵“墙”已经砌好,等着我们开“门窗”了。
2.3 开出“门窗”:使用 lvcreate 创建逻辑卷
现在,我们从vg_data这堵大墙上,开出我们需要的“门窗”——逻辑卷(LV)。这才是操作系统最终识别和使用的“磁盘设备”。
假设我们需要一个10G的空间来存放网站数据。命令如下:
[root@server ~]# lvcreate -n lv_web -L 10G vg_data
Logical volume "lv_web" successfully created.
这里,-n指定逻辑卷的名字lv_web,-L指定大小10G,最后跟上所属的卷组名vg_data。除了-L,你还可以用-l参数指定PE的个数来定义大小,比如-l 2560(因为10G / 4M = 2560),但直接指定容量显然更直观。还有一个超级实用的参数是-l +100%FREE,这表示“占用卷组里所有剩余空间”,在你想把整个VG空间都给一个LV时特别方便。
创建完成后,系统里就多了一个块设备。它通常有两个路径可以访问:
/dev/mapper/vg_data-lv_web(DM设备路径)/dev/vg_data/lv_web(符号链接路径)
这两个路径指向同一个内核设备(如/dev/dm-0),用哪个都一样。你可以用lvs或lvdisplay来查看它的详细信息:
[root@server ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_web vg_data -wi-a----- 10.00g
至此,一个逻辑卷就创建好了。但它现在还是一块“裸设备”,要像普通分区一样使用,还需要最后两步:格式化和挂载。
# 格式化,这里选择常用的xfs文件系统(根据你的发行版选择ext4或xfs)
[root@server ~]# mkfs.xfs /dev/vg_data/lv_web
# 创建挂载点并挂载
[root@server ~]# mkdir /data/web
[root@server ~]# mount /dev/vg_data/lv_web /data/web
最后,别忘了把挂载信息写入/etc/fstab实现开机自动挂载:
/dev/vg_data/lv_web /data/web xfs defaults 0 0
3. 空间不够了?动态扩容才是LVM的精髓
业务增长,数据量暴增,/data/web又快满了?别慌,这才是LVM大显身手的时候。扩容分为两步:卷组扩容(给存储池加新硬盘)和逻辑卷扩容(从池子里划更多空间给LV)。
3.1 给存储池加料:使用 vgextend 扩容卷组
假设我们新增了一块16G的硬盘/dev/sdd。首先,依然要把它初始化为物理卷:
[root@server ~]# pvcreate /dev/sdd
然后,使用vgextend命令,将这块新的PV加入到我们已有的卷组vg_data中:
[root@server ~]# vgextend vg_data /dev/sdd
Volume group "vg_data" successfully extended
就这么简单!现在用vgs看一下:
[root@server ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vg_data 3 1 0 wz--n- 29.99g 19.99g
看,卷组大小从~14G变成了~30G,空闲空间(VFree)变成了约20G(原有4G空闲 + 新加的16G)。我们的存储池变大了,但逻辑卷lv_web的大小还是10G,我们需要把这新增的空间分配给它。
3.2 给逻辑卷“增肥”:使用 lvextend 扩容逻辑卷
现在,我们把卷组里新增的(或者原有的空闲)空间,扩容给lv_web。假设我们想给它再增加5G空间:
[root@server ~]# lvextend -L +5G /dev/vg_data/lv_web
Size of logical volume vg_data/lv_web changed from 10.00 GiB (2560 extents) to 15.00 GiB (3840 extents).
Logical volume vg_data/lv_web successfully resized.
-L +5G表示在原有基础上增加5G。如果你想扩展到绝对大小,比如直接扩大到20G,可以用-L 20G。命令执行后,LV的底层空间已经扩大了。但是,操作系统和文件系统还不知道这个变化!这是新手最容易踩的坑:用df -h查看,挂载点大小还是原来的10G。
这是因为文件系统还停留在原来的大小。我们需要“通知”文件系统去占用新扩展的空间。根据你使用的文件系统类型,操作不同:
-
对于XFS文件系统(CentOS/RHEL 7+ 默认): XFS文件系统只支持在线扩容,不支持缩容。扩容命令是:
[root@server ~]# xfs_growfs /data/web # 或者指定设备 [root@server ~]# xfs_growfs /dev/vg_data/lv_web -
对于EXT2/3/4文件系统: EXT系列文件系统支持在线扩容和离线缩容。扩容命令是:
[root@server ~]# resize2fs /dev/vg_data/lv_webresize2fs命令如果不加大小参数,会自动扩展到底层LV的所有可用空间。如果你想只扩展到特定大小(比如14G),可以加参数resize2fs /dev/vg_data/lv_web 14G。
一个超级实用的“一条龙”命令:如果你使用的是ext4文件系统,并且想一次性将LV扩容到占用VG的所有剩余空间,可以这样操作:
# 1. 将LV扩展到卷组的所有剩余空间
[root@server ~]# lvextend -l +100%FREE /dev/vg_data/lv_web
# 2. 让文件系统同步扩展到LV的最大边界
[root@server ~]# resize2fs /dev/vg_data/lv_web
这个组合拳在管理数据盘时非常高效。完成文件系统扩容后,再用df -h查看,你会发现/data/web的容量已经变大了,而整个过程完全不需要卸载文件系统或重启服务,真正实现了动态扩容。
4. 进阶与风险操作:逻辑卷缩容全流程拆解
扩容是常规操作,但缩容(减小逻辑卷大小)就是一个需要谨慎对待的“高危”操作了。什么情况下需要缩容?比如你规划失误,某个LV分配过大,而同一个VG下的另一个LV急需空间;或者你需要从现有LV中剥离一部分空间创建一个新的LV。缩容的风险主要在于数据丢失,因为过程涉及文件系统的缩小,如果操作不当或中途断电,极易导致文件系统损坏。
核心原则:务必先备份数据! 这不是建议,是必须执行的铁律。整个缩容流程可以概括为:检查 -> 缩小文件系统 -> 缩小逻辑卷。顺序千万不能错!
我们以/dev/vg_data/lv_web(假设为ext4文件系统)从15G缩容到10G为例,演示完整步骤。
4.1 第一步:卸载与文件系统检查
为了绝对安全,缩容操作必须在卸载状态下进行。这会暂时影响服务,所以务必安排在业务低峰期。
[root@server ~]# umount /data/web
卸载后,使用e2fsck强制检查文件系统,确保其完全健康,没有错误。这个步骤是resize2fs命令强制要求的。
[root@server ~]# e2fsck -f /dev/vg_data/lv_web
e2fsck 1.45.6 (20-Mar-2020)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vg_data/lv_web: 12/983040 files (8.3% non-contiguous), 120342/3932160 blocks
-f参数表示即使文件系统看起来干净也强制检查。如果检查出严重错误,必须先修复才能继续。
4.2 第二步:缩小文件系统
这是最关键的一步。我们必须先把文件系统本身缩小到目标尺寸(10G)以下。绝对不能先缩小LV! 因为那样会直接截断数据,导致超出新LV边界的数据永久丢失。
使用resize2fs命令来缩小ext4文件系统:
[root@server ~]# resize2fs /dev/vg_data/lv_web 10G
resize2fs 1.45.6 (20-Mar-2020)
Resizing the filesystem on /dev/vg_data/lv_web to 2621440 (4k) blocks.
The filesystem on /dev/vg_data/lv_web is now 2621440 (4k) blocks long.
这个命令将文件系统精确缩小到10G。你可以先执行resize2fs /dev/vg_data/lv_web 9G,为后续LV缩容留一点缓冲空间,更安全。
4.3 第三步:缩小逻辑卷
文件系统已经变小了,现在我们可以安全地缩小底层的逻辑卷了。使用lvreduce命令:
[root@server ~]# lvreduce -L 10G /dev/vg_data/lv_web
WARNING: Reducing active logical volume to 10.00 GiB.
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce vg_data/lv_web? [y/n]: y
Size of logical volume vg_data/lv_web changed from 15.00 GiB (3840 extents) to 10.00 GiB (2560 extents).
Logical volume vg_data/lv_web successfully resized.
系统会给出严厉的警告,因为这是一个危险操作。因为我们提前缩小了文件系统,所以这里可以放心输入y。-L 10G是指定缩小后的绝对大小。如果你想缩小特定容量,比如减小5G,可以用-L -5G。
4.4 第四步:重新挂载与验证
操作完成后,重新挂载并检查:
[root@server ~]# mount /dev/vg_data/lv_web /data/web
[root@server ~]# df -h /data/web
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_data-lv_web 9.8G 4.2G 5.2G 45% /data/web
再用lvs命令查看,确认LV大小已变为10G。
重要警告:
- XFS文件系统不支持缩容! 如果你用的是XFS,缩小LV的唯一方法是备份数据、重建LV、恢复数据。
- 缩容前,务必确保文件系统已用空间小于目标容量。例如,你不能把一个存了8G数据的LV缩容到5G。
- 强烈建议在测试环境反复演练整个流程,熟练后再在生产环境操作。
5. 管理、移除与日常维护指南
掌握了创建和调整,日常管理同样重要。LVM提供了一套丰富的查看和移除命令。
5.1 查看信息的“三件套”:pvs/vgs/lvs 与 display/scan 系列
LVM为每一层都提供了三种查看命令,输出详略不同:
pvs/vgs/lvs:最常用,信息简洁明了,适合快速浏览。pvdisplay/vgdisplay/lvdisplay:输出最详细的信息,包括UUID、PE/LE数量、映射关系等,用于深度排查。pvscan/vgscan/lvscan:扫描系统并列出所有相关设备,输出最简单,常用于初始化或确认设备状态。
例如,想快速了解系统所有存储空间概况,一个vgs和lvs组合就够:
[root@server ~]# vgs; lvs
VG #PV #LV #SN Attr VSize VFree
vg_data 3 1 0 wz--n- 29.99g 19.99g
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_web vg_data -wi-ao---- 10.00g
可以看到,vg_data卷组还有约20G空闲,lv_web逻辑卷大小为10G且处于激活(a)和打开(o)状态。
5.2 如何安全地拆除:移除逻辑卷、卷组和物理卷
当你需要清理或重新规划存储时,需要从LV到VG再到PV,反向拆除。
1. 移除逻辑卷 (lvremove) 首先确保逻辑卷已卸载,然后直接移除:
[root@server ~]# umount /data/web
[root@server ~]# lvremove /dev/vg_data/lv_web
Do you really want to remove active logical volume vg_data/lv_web? [y/n]: y
Logical volume "lv_data" successfully removed
移除后,该LV占用的空间会返还给卷组。
2. 移除卷组 (vgremove) 在移除卷组内所有逻辑卷后,如果确定不再需要该卷组,可以将其移除:
[root@server ~]# vgremove vg_data
Do you really want to remove volume group "vg_data" containing 0 logical volumes? [y/n]: y
Volume group "vg_data" successfully removed
3. 移除物理卷 (pvremove) 最后,如果你希望一块硬盘彻底退出LVM管理(比如要拔掉或做其他用途),需要移除物理卷的LVM标签:
[root@server ~]# pvremove /dev/sdd
Labels on physical volume "/dev/sdd" successfully wiped.
执行pvremove后,该磁盘上的LVM元数据被清除,又变回了一块“干净”的磁盘。注意:如果物理卷还在某个卷组中,你需要先用vgreduce vg_data /dev/sdd将其从卷组中踢出,才能执行pvremove。
6. 实战经验与避坑指南
纸上得来终觉浅,绝知此事要躬行。结合我多年的经验,分享几个实战要点和容易踩的坑。
关于PE大小规划:创建VG时指定PE大小(-s)需提前规划。大PE(如64M)适合超大文件(视频、镜像),管理开销小;小PE(默认4M)适合小文件多的场景,空间利用率高。一旦VG创建,PE大小就不可更改。对于混合工作负载,默认4MB是安全且通用的选择。
关于LVM快照:LVM有一个杀手级功能——快照。你可以瞬间为一个正在使用的LV创建一个只读或可写的快照卷,用于数据备份、测试升级等,而无需停机。创建命令类似lvcreate -s -n snap_lv_web -L 2G /dev/vg_data/lv_web。但记住,快照卷会随着原卷的数据变化而增长,务必预留足够空间,并在使用后及时删除。
关于数据安全:LVM不是备份工具!它提供了灵活性,但没有额外的数据冗余。底层物理硬盘损坏,LV上的数据依然会丢失。对于重要数据,应在物理层使用RAID(如RAID1, RAID5, RAID6)提供冗余,再在其上构建LVM,实现“RAID保安全,LVM管灵活”的组合。
一个常见的“坑”:在虚拟化环境(如VMware、KVM)中给虚拟机添加新磁盘并扩容LVM时,有时操作系统内核无法立即识别新磁盘的大小。在执行pvcreate或vgextend前,可以尝试运行partprobe或echo 1 > /sys/class/block/sdX/device/rescan(将sdX换成实际设备名)来让内核重新读取磁盘信息。
LVM的灵活性极大地简化了存储管理,但它也是一把双刃剑。复杂的多层映射关系在带来便利的同时,也增加了问题排查的复杂度。养成好习惯:每次对LVM结构做重大变更前,使用vgcfgbackup命令备份VG的元数据;记录下重要的PV、VG、LV的UUID(用pvdisplay/vgdisplay/lvdisplay查看),在系统启动失败需要紧急恢复时,这些信息是救命稻草。
1712



被折叠的 条评论
为什么被折叠?



