我做过不少存储相关的运维和架构调整说句实话凡是跟分区打交道久了的人迟早会遇到“磁盘空间不够用”“分区大小不能改”“扩容要停机”这类让人头疼的事。LVM2Logical 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侧重的是容量灵活管理。它本身不替代RAIDRAID解决的是盘坏了不丢数据LVM2解决的是空间不够了能随时扩。两者各司其职可以完美组合。LVM2还额外提供了快照功能可以在极短时间内生成某个逻辑卷的“冻结副本”备份数据库和文件系统时非常好用。虽然它不是备份软件的替代品但作为备份前置手段价值巨大。2. 核心概念逐个拆解PV、VG、LV、PE一点都不玄乎LVM2的整套体系里概念不算多刚开始容易犯迷糊但只要你抓住一条主线就全通了把零散的物理存储PV汇集成一个大池子VG再从池子里抽出若干快小空间LV给系统用。2.1 PVPhysical Volume物理卷是地基PV是LVM2体系里的最小存储单元一个PV通常对应一块物理磁盘上的一个分区如/dev/sda1也可以是一整块磁盘/dev/sdb甚至是一个RAID阵列设备。把一块盘或分区初始化为PV本质上是往这个设备头部写入LVM2的元数据区域标记“这块空间由LVM2说了算”。一旦成为PV这块盘就不再适合直接当普通分区挂载使用了必须通过LVM2来管理。这里有一个我踩过的坑如果盘上已经格式化过且有数据执行pvcreate之前务必备份数据因为pvcreate会覆写设备头部元数据区域旧文件系统信息就没了。2.2 VGVolume Group卷组是资源池VG就是把所有PV整合后的“逻辑资源池”。你可以把它想象成一个蓄水池PV就是汇入水池的管道水池里的总容量就是各管道容量的总和。VGG给系统提供了一套统一调度的空间池后续所有LV都从VG里划分。VG里还有两个重要参数需要平时留意PEPhysical Extent物理扩展块VG分配空间的最小单位。创建VG时可以用-s参数指定PE大小默认为4MB。这就像水池里的水是用桶来计的每桶是统一标准。空闲空间VG里未被LV占用的剩余空间扩容LV时一般就是从这部分空间里调拨。PE大小会影响后续LV操作的余量。如果PE太小大容量VG在分配时元数据会稍多而且扩展时要算的块数也更多如果PE太大比如1GB那么创建一个小LV时可能就被凑整到1GB起步浪费空间。综合考虑大多数场景用默认的4MB就足够只有超大容量存储池才建议调大。2.3 LVLogical 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一行一行看效果第一步把三块盘都初始化为PVpvcreate /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的总容量正好是203050100G空闲空间也是100G。这里我一般会加上PE大小参数虽然默认4MB就够用但在演示或较大空间规划时显式指定能让后续计算更清晰比如vgcreate vg_data /dev/sdb /dev/sdc /dev/sdd -s 16M把PE设为16MB后后面按PE数量分配时每一个PE就是16MB计算起来很直观。第三步从vg_data里创建一个20G的逻辑卷名字叫lv_datalvcreate -L 20G -n lv_data vg_data也可以换用PE数量方式。如果PE采用16MB2048除以16等于128所以创建20G等价于128个PElvcreate -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拿到逻辑卷的UUIDblkid /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缩到25Gresize2fs /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安装lvm2pvcreate拒绝设备上有旧签名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时用resize2fsxfs时用xfs_growfs。xfs只支持扩大不支持缩小所以对xfs卷千万别做lvreduce一旦缩了基本等于自找麻烦。备份这件事更要刻进肌肉记忆里。LVM2快照虽好用但快照只在原卷的物理空间正常时才有意义。如果整块物理盘报废快照也一起没了。真正的备份还要落到异机或对象存储里。快照适合做“时间点回滚”和“备份期间的数据一致性保障”但它替代不了“备份”。我自己的习惯是对每一台服务器都建一个文本文档记录VG、LV、PV的规划表包括创建时间、扩容历史、快照操作记录。这个习惯救过我很多次尤其是机器多了以后靠记忆根本扛不住。配合lvmdiskscan、pvs、vgs、lvs这些只读命令定期巡检能提前发现空间不足和PV故障隐患。最后再分享一个我觉得很实用的小技巧当你给数据库、容器镜像目录这类I/O密集场景创建逻辑卷时可以让LV不占满整个VG保留20%左右空闲空间。这20%平时看似浪费但关键时刻能让你不做任何停服操作就完成一次紧急扩容甚至能让你原地打一个足够大的快照。存储运维的核心不是等事情发生了再去救火而是把未来半小时能遇到的风险提前到过去五分钟就规避掉。
