
接到那台服务器的时候我完全没预料到“/data 快要满”这条告警会把我拖进一场关于磁盘管理的连夜排查。Linux里的磁盘管理平时存在感极低一旦出问题就是火烧眉毛尤其是当你发现当初安装时把所有分区都规划死了根本没有预留任何扩展余地时就会深刻理解LVMLogical Volume Manager逻辑卷管理到底解决了什么问题。后来我花了几个晚上把LVM从原理到实战完整过了一遍也顺便处理了云电脑加入数据盘后重装系统前必须拆LVM这个高频坑。这篇文章就按照我之前实际做过的项目流程来写覆盖创建、扩容、缩容、重装前的安全卸载、Ubuntu和国产系统Kylin的扩容差异以及我踩过的一堆坑。适合刚接手Linux服务器的运维新人、要给云主机或云电脑重装系统的朋友以及面试前想快速把LVM体系梳理清楚的人。1. 为什么我会死磕Linux磁盘管理项目背景与实际需求1.1 一个深夜告警让我翻出的旧账当时环境并不复杂一台云平台上的Linux虚拟机系统盘40G数据盘200G。安装系统时不知道谁选了LVM方案而且把系统盘和数据盘都放进了同一个卷组Volume Group。白天运行看不出问题可数据盘写入一涨整个卷组的可用空间就告急最尴尬的是根分区和业务分区共享一个空间池想单独给业务扩容都做不到。后续每次扩容都是一套固定动作到云控制台加一块云盘进入系统创建物理卷把新盘扩充进卷组再把逻辑卷拉大最后调整文件系统。这套流程本身并不难真正让人头疼的是云电脑/云主机场景下最常见的定时炸弹如果这台机器用了LVM而且数据盘被加进了卷组那么重装系统之前必须先把这个数据盘从LVM里安全拆出来。否则新系统初始化时要么识别不到数据盘要么被残留的LVM元数据干扰直接卡在启动阶段。这个坑我在第4节详细展开先把地基打好再说。1.2 传统分区和LVM的分水岭在哪很多朋友对磁盘管理的印象还停留在“fdisk 划个分区、mkfs 格式化、mount 挂载”三步曲。确实传统MBR/GPT分区方案简单直接但对运维非常不友好根分区空间不够只能重新分区再迁移数据想跨两块物理盘合并成一个目录传统分区几乎做不到想给业务目录做快照备份传统方案得依赖文件系统级别的支持。LVM的核心思路是把“物理磁盘大小”和“文件系统看到的大小”彻底解耦。它引入了一个中间层可以把多块物理磁盘看成一个大资源池再从这个池里按需切出虚拟的“逻辑卷”。文件系统以为自己在读写一块真实块设备实际上底层数据可能分散在一块、两块甚至多块盘上。这个架构带来的直接收益是扩容量、迁移数据、做快照都从“动刀手术”变成了几条命令。1.3 这个项目实际要解决的问题清单已有LVM环境的逻辑卷扩容比如从20G扩到60G云电脑加入数据盘并纳入LVM后重装系统前如何安全拆出根分区是LVM的Ubuntu系统如何在线扩容不打乱业务国产系统Kylin等环境下用LVM扩容有哪些差异和坑反过来想清楚什么场景根本不该用LVM避免过度设计后面所有章节都围绕这五条实际需求展开不搞纯理论。2. LVM核心原理把硬盘变成一池可以重新浇筑的沙子2.1 四个关键概念一次讲透我习惯用一个类比来记忆LVM传统分区像一块块已经浇筑好的水泥板宽度写死了想改只能砸而LVM像乐高积木随时可以加积木、挪积木、拆掉局部重建。具体到术语上PVPhysical Volume物理卷乐高里的“砖块”。一块硬盘或一个分区打上LVM标记后就成为PV标记动作是pvcreate。VGVolume Group卷组乐高的“底板收纳盒”。多个PV合并在一起形成一个统一的大容量空间池池子多大取决于你放进了多少块砖动作是vgcreate。LVLogical Volume逻辑卷从池子里切出来的“预制板”。文件系统就住在上面对应/dev/vgname/lvname这样的设备路径动作是lvcreate。PEPhysical Extent物理扩展块和LELogical Extent逻辑扩展块整个系统的“最小颗粒”默认4MiB。池子容量按4MiB为单位切成小格子逻辑卷占多少格子、数据落在哪块砖的哪个格子里全靠元数据记录。lvextend本质就是调整LV占据的格子数量。如果对内存管理熟悉可以换个角度理解PV相当于物理内存页LV相当于进程看到的虚拟地址空间VG就是管理整张映射页表的内核内存管理单元。文件系统只看到LV这个虚拟设备底层数据到底放在哪块盘的哪个PE上它根本不用关心全由映射表负责。2.2 弹性到底从哪里来传统分区表一旦划好sda1的起止扇区就固定了想变大得靠各种“邪门”操作。而LVM的逻辑卷大小说白了只是元数据里的一段记录该LV建立了多少个LE的映射。扩容时系统从VG的空闲PE池中分配新的LE追加到LV的映射链上再把文件系统层同步扩大。因为整个过程只改了映射表完全可以在线完成不用卸载业务、不用重启生产环境也能操作。这正是LVM存在的意义。2.3 快照和跨盘聚合的设计思想快照是LVM的杀手级功能原理就是Copy-on-Write写时复制。拍快照时并不会复制整个逻辑卷而是只记录“原卷哪些块即将被覆盖”。当新数据要写入原卷时系统先把旧数据块拷贝到快照卷再做覆盖。所以创建快照几乎一瞬间就完成空间占用只随增量数据变化。但快照不是免费的午餐后面第7节我会专门讲快照写满之后会把整个VG卡死。跨盘聚合则是把多块物理盘PV加进同一个VG这样逻辑卷可以跨硬盘分布对数据库这类大目录特别有用。代价是IO路径比裸设备多了一层映射某些极端场景下会有性能损耗第6节我会给出我的实测结论。3. 从零搭建一套LVM完整命令与参数解析3.1 环境准备与分区规划用一个刚挂载了两块数据盘的虚拟机做演示一块5G的sdb一块10G的sdc。目标是创建一个名叫vgdata的卷组从里面切出15G的逻辑卷挂到/data目录。第一步用fdisk把sdb、sdc划成LVM分区。这里有一个经验细节整块裸盘直接做PV也可以但为了防止未来分区表被误识别业界普遍建议在裸盘上先建一个类型为LVM的分区。MBR分区表下类型代码是8e操作过程如下fdisk /dev/sdb # n - p - 1 - 回车 - 回车默认占满全盘 # t - 8eLinux LVM # p 确认分区表 # w 保存对 /dev/sdc 重复同样操作得到 /dev/sdb1 和 /dev/sdc1用lsblk /dev/sdb /dev/sdc确认即可。注意fdisk写完分区后如果系统没刷新分区表执行partprobe /dev/sdb或者重启。如果用parted做GPT分区LVM分区类型代码要换成8300或8e00不同工具混用时格外小心分区表格式差异。3.2 创建PV、VG、LV以及格式化挂载创建命令依次是pvcreate /dev/sdb1 /dev/sdc1 vgcreate vgdata /dev/sdb1 /dev/sdc1 lvcreate -L 15G -n data vgdata先说选型逻辑vgdata是卷组名data是逻辑卷名。如果不指定-L而是用-l 100%FREE就会把整个VG空间全部切给这个LV。但生产环境我强烈建议至少留出10%-20%余量因为VG剩余空间一旦为零后续做缩容、快照、修数据都会非常被动。格式化并挂载mkfs.ext4 /dev/vgdata/data mkdir -p /data mount /dev/vgdata/data /data文件系统我特意选了ext4因为它支持在线扩容也支持缩容虽然缩容有风险。如果业务是单个超大目录、海量小文件可以考虑xfs但xfs不支持缩容后续如果想调小空间会非常难受。3.3 开机自动挂载与常用查询命令mount是临时的重启就失效必须写进 /etc/fstab。我的建议是不要直接写设备路径而是写UUID因为设备名在重启后可能因为磁盘枚举顺序变化而错位blkid /dev/vgdata/data echo UUID你的uuid /data ext4 defaults 0 2 /etc/fstab mount -a平时最常用的LVM状态查看命令我理成一份清单pvs看物理卷概况vgs看卷组总容量、剩余空间lvs看逻辑卷大小pvdisplay / vgdisplay / lvdisplay看详细元数据lsblk -f看文件系统类型和挂载点df -hT看实际可用空间很多面试题会问“LVM怎么看剩余空间”标准思路是先vgs看VG Free再lvs看LV大小最后df -h看文件系统层实际用量。这三层分别对应分配层、映射层、业务层千万别用df代替vgs做容量规划。3.4 完整扩容演示从20G扩到60G换一个更真实的场景当前 /data 的逻辑卷是20G业务量暴涨需要扩到60G但VG空间不够所以先在云控制台给机器加一块40G的新盘。# 新云盘添加完成后通常显示为 /dev/sdd pvcreate /dev/sdd1 # 或者 pvcreate /dev/sdd vgextend vgdata /dev/sdd1 lvextend -L 60G /dev/vgdata/data resize2fs /dev/vgdata/data # ext4在线扩容 df -hT /data这里有几个实战要点按重要程度排操作顺序一定是先扩底层LV再扩上层文件系统。反过来执行resize2fs大概率报错。resize2fs在默认情况下会自动探测逻辑卷的新大小不需要手动填写块数。如果LV已经扩了但df -h没变化90%是漏了resize2fs这一句。如果文件系统是xfs扩容命令是xfs_growfs /data不是resize2fs命令用错会直接报错。4. 重装系统前如何安全“拆”掉LVM数据盘4.1 为什么重装前必须处理LVM数据盘这是我被问到最多的问题也正对应着一些热搜里说的“云电脑使用了LVM并加入了数据盘重装前需要先从LVM卸下”。原因其实很现实云主机重装系统时系统盘一般会被重新初始化而数据盘因为保着数据通常不会格式化。但如果数据盘在旧系统里加入了LVM它分区头部就会带上LVM元数据新系统启动时LVM会主动扫描磁盘并尝试激活旧卷组。如果因为残留配置、UUID冲突、或者激活时找不到某些PV启动过程非常容易卡住甚至直接掉进EMERGENCY MODE。更麻烦的是旧系统把数据盘和系统盘塞进同一个VG重装时系统盘被格式化卷组元数据被撕成两半数据盘上的PV标记还指向那个已经四分五裂的VG。这时候不但历史逻辑卷看不见连VG本身都会变成僵尸状态。所以云电脑场景下数据盘一旦加入过LVM重装前必须摘干净。4.2 安全卸载的完整流程在重装前的旧系统里执行以下操作按顺序来不要跳步。第一步先把重要数据备份走。LVM操作不是零风险容错率全看备份做没做。第二步确认当前LVM拓扑并记录pvs vgs -v lvs lsblk -f把VG名、PV设备、LV名、挂载点全部记下来。这一步看起来多余但在恢复阶段能救命。第三步卸载与该VG相关的所有逻辑卷umount /dev/vgdata/data # 如果有swap在LV上执行 swapoff /dev/vgdata/swap_lv确认没有挂载占用后停用整个VGvgchange -an vgdata这里a是active激活状态n是no作用是让VG进入非激活状态不再往相关PV上写元数据。执行后可以用vgdisplay vgdata确认VG Status显示为 NOT available。第四步如果你确认数据盘上的数据不再需要保留并且想让数据盘彻底忘记LVM身份可以继续执行vgreduce vgdata /dev/sdb1 # 仅当该PV上没有任何LV数据时 pvremove /dev/sdb1 # 清除LVM元数据标记如果数据盘上是有用的数据逻辑卷不要执行vgreduce和pvremove做到vgchange -an这一步然后关机再重装即可。重装完成后在新系统里重新扫描导入。4.3 重装后重新挂载数据盘的两种方式我实测下来有两条恢复路径说下区别。方式一数据盘在旧系统里是独立VG重装过程没有动过这块盘。新系统装好后直接执行vgscan vgchange -ay vgdata ls /dev/vgdata/ mkdir -p /data mount /dev/vgdata/data /datavgscan会自动扫描所有磁盘头部把旧VG元数据重新识别出来vgchange -ay是重新激活。前提是旧VG的所有PV在重装过程中都没被动过。方式二新系统识别不到旧VG或者PV报“Couldnt find device with uuid”错误。这种情况通常需要vgimportclone重建各PV元数据或者用vgcfgrestore手工恢复备份。这个属于故障恢复了详细的我放在第7节讲。4.4 拆装过程中容易踩的三个坑坑一执行vgchange -an之前忘了umount。系统会报 target is busy卸载失败。解决思路是先确认没有进程占用挂载点用lsof /data或者fuser -km /data清理。坑二逻辑卷用了xfs而且你在重装前顺手做了缩容操作。xfs不能缩容硬来会直接报错。别问我怎么知道的xfs挂在VG里时缩容只能靠迁移数据重建逻辑卷。坑三重装后挂载数据盘文件系统变成了只读。大概率是VG元数据没激活或者UUID冲突。先看dmesg | tail输出再决定要不要用fsck -f /dev/vgdata/data修复。注意fsck必须先umount否则容易二次损坏。5. 根分区扩容实战Ubuntu与国产系统Kylin的差异化处理5.1 Ubuntu根分区扩容全流程Ubuntu服务器版安装时如果勾选LVM选项根分区一定是一个逻辑卷。这种场景下扩容根分区是最常见的需求。完整流程是先在云控制台/虚拟化平台把系统盘从40G扩到80G再进系统执行lsblk fdisk /dev/sda # 把原分区删掉重新创建同样起点、占满全盘的分区 # 分区类型保持不变起始扇区不能变 partprobe /dev/sda cat /proc/partitions # 确认内核看到新大小 pvresize /dev/sda2 # 把PV扩展到新分区大小 lvextend -l 100%FREE /dev/ubuntu-vg/ubuntu-lv resize2fs /dev/ubuntu-vg/ubuntu-lv df -h这里很多人不敢动的是fdisk删除分区重建这一步。其实只要保证起点不变、类型不变数据不会丢。但一旦在重建分区时改变了起始扇区数据损坏几乎是必然的所以操作之前一定要用parted /dev/sda unit s print把当前分区起始扇区记下来。参数-l 100%FREE表示把VG里所有剩余空间全部给该LV根分区扩容时我推荐这么写比手算-L 40G要稳得多因为手算一旦算错剩余空间后续报错会让人头大。5.2 国产系统Kylin扩LVM时的适配差异国产系统、比如银河麒麟V10这类虽然是Linux生态但默认策略往往更保守实测中我遇到过几个差异点第一默认可能装了lvm2核心工具但缺少一些文档和辅助工具包。如果遇到lvcreate找不到设备先确认内核dm模块是否加载ls /dev/mapper/ dmesg | grep -i dm第二某些国产系统安装器生成的VG名称带大写字母或特殊前缀命令严格区分大小写执行前先用vgs确认实际名字。另外系统默认可能开启saned扫描扩容后建议重启图形环境或刷新会话否则桌面环境仍显示旧容量。第三Kylin如果根分区是ext4、/boot独立分区扩容根LV前建议先检查 /boot 剩余空间。如果/boot满了根LV扩得再大后续系统更新也可能失败这两个问题是互相牵连的。我把这些差异列出来是想说明LVM本身通用但每个发行版在封装、默认工具链、策略上会有差异。遇到问题优先查dmesg、/var/log/messages和initramfs配置不要急着重装系统。5.3 扩容中的安全注意事项根分区扩容不管是Ubuntu还是Kylin有几条铁律不能破操作前必须完整备份。根分区上都是系统文件一旦损坏修复成本远高于数据盘。fdisk重建分区前先把原分区信息拍照保存命令历史不要清。扩容到100%FREE时先确认VG里有没有快照卷。快照卷会占用空间不释放的话会影响分配。不要同时扩多个逻辑卷除非非常确定VG剩余空间充足。空间分配失败会留下一半元数据变化排查非常麻烦。扩容过程中不要对磁盘执行额外的dd、mkfs操作避免干扰分区表。6. LVM的优缺点与适用场景别让工具绑架架构6.1 优点盘点弹性、聚合、快照、在线操作LVM最大的价值一句话说就是它把磁盘管理从“改户型”变成了“砌模型”。传统分区像墙体已经浇筑好了想改只能砸LVM是乐高积木随时可以加积木、挪积木、拆局部重建。具体优势有四个在线扩容生产不用停机lvextend加resize2fs就能完成配合云平台加盘基本5分钟搞定。跨盘聚合两块500G的老盘可以合并成1T的卷组再切出任意大小的逻辑卷。老机器攒磁盘非常实用。快照备份、测试环境、升级回滚都靠它。一秒创建的快照非常适合当升级前的“后悔药”。动态缩容ext4理论上支持lvreduce虽然我不建议在生产环境干这事但测试环境灵活性确实高。6.2 痛点总结性能、复杂度、排错成本LVM也远不是银弹。性能上IO路径比裸设备多了一层Device Mapper映射。对高IOPS的数据库场景理论损耗大约在5%左右。硬件性能越强损耗越不容易感知但如果是机械硬盘承载的高并发业务映射层的开销会被放大。复杂度也是一笔隐性成本概念多、命令多、元数据存放位置隐蔽。一旦PV乱了、VG丢了、LV依赖关系复杂排查难度远超普通分区。快照用不好还能把整个VG空间耗尽导致生产直接挂起。另外早期版本使用lvmetad缓存某些系统尤其国产系统开机时会出现lvmetad与udev的竞态启动卡住的概率比传统分区高这些都是实际运维里看得见摸得着的代价。6.3 选型建议什么项目该用、什么不该用基于我的实际经验给出下面的选型建议生产服务器/数据库机器数据盘强烈建议用LVM同时保留20%以上VG余量系统盘是否LVM取决于发行版默认方案Ubuntu默认用了就继续用CentOS/Rocky系列默认非LVM就不必强行改动。容器宿主机推荐LVM thin pool或LVM快照配合容器存储做分层很方便。云主机/云电脑如果云平台本身支持云盘扩容和镜像快照系统盘其实可以不搞LVM免得重装时出现“数据盘绑定旧VG”的麻烦。如果已经用了LVM就严格按照第4节的方式安全拆装。嵌入式/ARM开发板能不装就不装。启动阶段多一层依赖SD卡、eMMC这类存储掉电后元数据恢复很麻烦。个人学习环境放心用多踩坑是好事试错成本低。7. 常见问题速查与独家排错心得7.1 高频问题排查速查表我把运维中高频碰到的LVM问题整理成一张表遇到直接对照症状可能原因优先排查/解决lsblk能看到盘但pvs找不到未执行pvcreate或分区类型不是8e用pvcreate /dev/sdd1再用fdisk确认typevgs显示有Free但lvextend报No spaceVG里存在快照卷或PE个数不足用lvs查看所有LV和快照清理或释放空间开机卡在Local File Systems之前lvmetad缓存或initramfs不完整调整/etc/lvm/lvm.conf缓存配置重建initramfsmount报unknown filesystem typeLV未激活或文件系统元数据损坏先vgchange -ay激活再考虑fsckxfs分区扩容后df没变化用错命令xfs需要xfs_growfs执行xfs_growfs /挂载点VG状态显示NOT availablePV设备丢失或vgchange -an未恢复检查磁盘接入执行vgchange -ay激活VG报Couldnt find device with uuidPV元数据里的设备路径/UUID与实际不符用pvs -o uuid查实际UUIDvgcfgrestore或vgimportcloneLV空间够但df还是旧容量缺少resize2fs/xfs_growfs先lvdisplay确认LV再扩文件系统层快照写满后整个VG锁死COW空间不足导致写入暂停不要删业务LV先扩大快照或删除快照再恢复写入dm_mod未加载导致设备不存在内核dm模块未编译或未加载modprobe dm_mod检查initramfs7.2 我踩过坑之后的几条铁律操作LVM这么多年有些原则是用事故换来的覆盖率极高铁律一对LVM的操作永远先备份再行动。尤其是生产环境重装前、缩容前、改VG前先执行vgcfgbackup导出VG元数据。恢复时一句vgcfgrestore vgdata -f /etc/lvm/backup/vgdata能救回整条命。铁律二不要轻易把整个VG删掉重建。很多朋友看系统卡死就想到vgremove但这是毁灭性操作。先确认LV里有没有数据先卸载再一步步处理PV。铁律三多层存储环境里比如云盘加物理机再加多路径PV最好加--metadatacopies参数明确指定元数据副本位置并定期执行vgck做元数据一致性检查。铁律四物理机换盘后如果pvs状态显示unknown device优先跑vgextend --restoremissing或vgcfgrestore不要直接vgreduce否则会把LV的一部分元数据丢掉。铁律五生产环境根分区最好不要和业务数据放在同一个VG里。两个VG各自独立互不拖累。这是我经历多次事故后最终推荐的架构没有之一。回头看我最初接到的那台服务器其实只用不到一个小时就把 /data 从爆满状态恢复到了余量30%。操作本身无非是lvextend加resize2fs真正的难点在于我第一次处理时完全没有预案不知道数据盘和VG的绑定关系、不确定重装系统会不会影响数据盘、也不清楚国产系统上部分命令行为会有偏差。所以我这次才特意按“重装前必须拆LVM、扩容顺序、常见故障”的顺序整理出来希望能帮你少走几个月的弯路。最后再提醒一句无论你用什么方案先备份再动手。磁盘世界里最贵的从来不是扩容时掏钱买的云盘而是那些一旦清了就再也找不回来的数据。