
这个系列写到第17篇了前面几篇把OpenEuler 24.03的安装、网络配置和服务管理都过了一遍评论区一直有朋友追着问安装时分区到底怎么选根目录满了怎么办给home扩容到底要不要重启这些问题背后其实都指向同一个技术点——LVM逻辑卷管理。在OpenEuler 24.03里从你点下自动分区那一刻起LVM就已经接管了整块磁盘根目录、home目录都住在逻辑卷里设备名也不再是熟悉的 /dev/sda2而变成了 /dev/mapper/openeuler-root 这种样子。如果不理解这套抽象扩容、快照、数据盘迁移这些日常操作就无从谈起。这篇文章我按自己平时排障的思路来写先解释为什么OpenEuler默认要用LVM再把PV、VG、LV这些概念用大白话讲透然后从创建到扩容、快照、故障排查给出一套可以直接照抄的命令序列。适合刚上手OpenEuler的运维新人也适合用过LVM但总在细节上踩坑的老手。个人经验优先能帮大家少走弯路。1. 为什么在OpenEuler 24.03上要用LVM1.1 装完系统后你的磁盘其实早就是LVM很多朋友第一次装完OpenEuler打开终端执行 lsblk看到输出里不是 sda1、sda2 这种简单的分区名而是 openeuler-root、openeuler-home 这样的设备路径第一反应是怀疑自己安装选错了。没有选错。OpenEuler 24.03的安装器在自动分区方案下默认采用LVM会单独切一个 /boot 普通分区用于存放内核和引导文件而根目录、/home 以及其他业务分区全部放在一个或多个逻辑卷里。为什么安装器要这么做因为LVM给系统预留了后悔药。传统分区方案下 / 和 /home 是两块独立的物理分区中间空余空间没法自由调配LVM方案下 / 和 /home 只是同一个资源池里的两个租户谁空间不够随时可以把资源池里剩余空间划给谁甚至不用重启。判断当前系统是否用了LVM命令很简单lsblk pvs vgs lvslsblk 看的是设备和挂载点的对应关系pvs、vgs、lvs 是LVM自己的三张视图分别显示物理卷、卷组、逻辑卷。如果在输出里看到了 vg 层面的信息那LVM就在工作。1.2 传统分区和LVM的关键差别我经常跟同事打一个比方传统分区相当于买房房间隔断是砖墙想改格局必须砸墙动静很大LVM相当于租了个大开间用移动隔板分区今天想要大客厅就拉大隔板明天想要大卧室再推回去。具体差异看这张表对比项传统分区LVM扩展方式需要重新分区通常要停机卷组有剩余空间即可在线扩展跨磁盘单块物理盘一个卷组可以跨多块物理盘缩容从头分区再同步数据理论上支持缩容但受文件系统限制XFS不可缩快照依赖文件系统层LVM原生支持秒级创建数据迁移需要dd或rsyncpvmove在线迁移业务无感故障排查相对简单多一层抽象启动时依赖lvm2服务看起来LVM几乎全胜但代价是系统启动链路里多了一个lvm2组件。如果在救援模式里忘了激活卷组你可能会连自己的数据盘都找不到。这个坑后面专门聊。1.3 LVM帮我解决的真实问题举几个我实际遇到的场景。第一类是根分区被日志写满系统告警如果是传统分区只能想办法删日志删完了还是焦虑LVM方案直接从卷组匀10G给根分区lvresize 加一条 xfs_growfs几十秒搞定。第二类是数据库服务器加了块新盘当时没规划好后续要并入已有数据目录LVM只要 pvcreate 再 vgextend旧数据完全不用动。第三类是日常发布前给业务卷打快照出问题5分钟内回滚这在传统分区时代几乎不敢想象。这些体验足够说明在OpenEuler这种长期稳定运行的系统里LVM是值得养成的存储习惯。2. LVM基础概念和完整创建流程2.1 PV、VG、LV、PE用一杯水讲清楚LVM术语看起来唬人拆开看就四个东西。PVPhysical Volume物理卷是把一块硬盘或者硬盘分区初始化为LVM能识别的存储单元相当于你买回来的矿泉水瓶是可以使用的原材料。VGVolume Group卷组是把多个PV拼在一起形成的资源池相当于把好多瓶水倒进一个大桶里桶的容量是所有瓶子之和。LVLogical Volume逻辑卷是从VG这个大桶里舀出来的水挂载到系统后就是一个虚拟分区用户可以像使用普通分区一样使用它。PEPhysical Extent物理扩展块是VG分配空间的最小单位默认4MB可以理解成舀水的勺子大小每次分配都以PE的整数倍进行所以有时候你看到LV大小和命令里写的数值不是完全一致多半是PE对齐造成的。弄懂这四个概念后LVM整套命令体系就很好记了pv开头的是操作物理卷vg开头的是操作卷组lv开头的是操作逻辑卷。2.2 从一块新硬盘开始完整创建LVM下面我用一台虚拟机现场演示新加一块10G的硬盘设备名是 /dev/sdb目标是创建一个5G的逻辑卷挂载到 /data。第一步初始化PVsudo pvcreate /dev/sdb输出会显示 Physical volume /dev/sdb successfully created。这里我特意用了整块盘而不是分区现代LVM完全支持直接基于整块裸盘创建PV如果你希望保留分区表可以先用 fdisk 把磁盘分区再把分区类型改成 8eLinux LVM然后 pvcreate /dev/sdb1。第二步创建VGsudo vgcreate data_vg /dev/sdb第三步从VG里创建LVsudo lvcreate -n data_lv -L 5G data_vg说明一下参数-n 指定逻辑卷名字-L 指定容量。创建完之后 /dev/data_vg/data_lv 这个设备就出现了也可以使用 /dev/mapper/data_vg-data_lv 访问它。第四步在LV上格式化并挂载sudo mkfs.xfs /dev/data_vg/data_lv sudo mkdir -p /data sudo mount /dev/data_vg/data_lv /data提醒一句OpenEuler默认文件系统是XFSXFS的扩容只能加不能减这一点后面会反复强调。如果你需要一个能缩容的文件系统格式化时就该选ext4。2.3 挂载持久化fstab里的两个坑mount命令只能临时挂载重启就失效。要让系统开机自动挂载把下面这行加进 /etc/fstab/dev/mapper/data_vg-data_lv /data xfs defaults 0 0不过这里有两个我踩过的坑值得单独拿出来说。第一个坑是Device Mapper路径的横杠问题。在 /dev/mapper 下卷组名和逻辑卷名之间用横杠分隔但如果卷组名或LV名本身带横杠比如 vg-test 配 lv-data那路径就会变成 /dev/mapper/vg--test-lv--data横杠会翻倍。这个规则很容易把新人绕晕所以我的习惯是用UUID代替设备路径。执行 blkid /dev/data_vg/data_lv 拿到UUID然后UUIDxxxx-xxxx /data xfs defaults 0 0第二个坑是校验。改完fstab后一定执行 mount -a 或者直接 reboot别等到登录不了了才想起来。之前有同事在文本编辑器里写错一个单词重启后系统直接进入emergency mode排查半天才发现是fstab格式问题。改fstab这事万无一失的做法永远是改完立刻验证。3. 给home目录扩容的完整实操步骤3.1 扩容前先把三层结构看清楚扩容是Linux运维里最高频的操作但很多人上来就是执行 lvextend然后发现 df -h 里的容量根本没变化于是开始怀疑人生。其实扩容是一个涉及三个层面的操作先看VG这个资源池里还有多少水再看LV这条水管要不要换粗最后文件系统这个水龙头也要打开。大多数失败案例都是忽略了最后一步。动手之前我建议按顺序执行四条命令df -hT vgs lvs pvdisplaydf 看文件系统当前容量和格式vgs 看卷组剩余空间VFree列lvs 看逻辑卷的当前大小pvdisplay 确认物理盘状况。这四条命令执行完你对全局就心里有数了。3.2 同卷组内扩容两步走别少一步假设当前 /home 对应逻辑卷 /dev/openeuler/home容量20Gvgs显示卷组剩余30G。想把 /home 扩到50G执行sudo lvextend -L 50G /dev/openeuler/home注意 -L 后有没有 号的区别-L 50G 是扩容到50G-L 20G 是在原来基础上增加20G。我的习惯是扩容用加号因为意图更明确不会因为记错当前容量把卷给缩小了。然后调整文件系统。如果 /home 是XFS执行sudo xfs_growfs /home如果 /home 是ext4执行sudo resize2fs /dev/openeuler/homeXFS和ext4的扩容命令参数完全相反xfs_growfs 后面跟挂载点resize2fs 后面跟设备文件。这一点太容易混淆了我在生产环境里见过不止一个人对着XFS文件系统运行 resize2fs结果直接把文件系统搞损坏。嫌两步麻烦的话新版lvm2支持 -r 参数一键完成sudo lvextend -r -L 20G /dev/openeuler/home-r 表示调整LV的同时自动调用文件系统扩容工具。实测下来这个参数很稳但我建议第一次用的时候还是先手动走一遍流程真正理解发生了什么再用自动化参数。3.3 卷组空间不够先扩VG再扩LV如果说 vgs 显示 VFree 为0这时候就得从物理层想办法了。常见做法是给虚拟机或者物理机加一块新盘。假设新盘是 /dev/sdc执行sudo pvcreate /dev/sdc sudo vgextend openeuler /dev/sdc第一条命令把新盘变成PV第二条命令把它并入现有的卷组。执行完再 vgsVFree应该已经从0变成新盘的容量了然后就可以继续执行 lvextend。这里有一个虚拟化环境特别常见的现象磁盘已经在虚拟机设置里加好了但 lsblk 看不到。别急这不是你操作的问题是SCSI子系统没有及时扫描到新设备。执行echo - - - /sys/class/scsi_host/host0/scan如果还是看不到把 host0 换成 host1、host2 再试或者用 lsscsi 查看当前有哪些SCSI主机。扫描这个动作不会破坏数据可以反复执行直到 lsblk 看到新盘为止。4. LVM快照和精简池给数据上双保险4.1 快照升级之前打一发秒级回滚LVM快照是我在所有Linux服务器上都会用到的功能。它的原理不是复制数据而是写时复制Copy-On-Write创建快照那一刻LVM只记录源LV的元数据状态几乎瞬间完成之后源LV上每发生一次新的写入旧数据才会被复制到快照空间里保存。所以快照刚创建时几乎不占空间随着源LV数据不断变化快照占用才会逐渐增长。创建快照的命令sudo lvcreate -s -n home_snap -L 5G /dev/openeuler/home-s 表示快照-n 指定快照名-L 是快照空间大小。快照空间给多大有讲究如果源LV平时写入量很小5G就够如果是频繁写入的数据库目录建议给源LV的20%以上。快照空间一旦写满快照就会失效甚至可能导致源LV暂停工作所以宁可给大一点。查看快照和使用情况lvs输出里能看到快照的 Data% 或 Snap% 列越接近100%越危险。需要回滚时先卸载源LVsudo umount /home sudo lvconvert --merge /dev/openeuler/home_snap sudo mount -amerge完成后快照卷会自动消失源LV恢复到快照创建那一刻的状态。我自己的习惯是每次升级内核、升级数据库、跑批量脚本之前都先打一个快照出问题三分钟回到之前的状态安全感和幸福感都很高。4.2 精简池把100G当400G规划如果只是单块盘、单卷组上面的用法完全够用。但如果你在跑虚拟化平台或者开发测试环境要批量创建几十个业务卷每个卷实际用量都不大这时候传统的预先分配模式就很浪费。LVM的精简池thin pool就是为这种场景准备的。精简池的精髓在于超卖你创建一个物理上只有50G的精简池却可以在里面创建多个虚拟容量为100G的精简卷实际占用按写入量动态增长就像容器镜像的分层存储看起来很大实际只占一小块。创建精简池sudo lvcreate -T -L 50G -n thinpool openeuler在池里创建精简卷sudo lvcreate -T openeuler/thinpool -n dev1 -V 100G注意 -V 后面的是虚拟容量可以远大于池的物理容量。创建完的精简卷格式化和挂载方式跟普通LV一样。用精简池必须配置自动扩展否则池撑满会发生连锁反应所有精简卷一起出问题。编辑 /etc/lvm/lvm.conf确认下面两行的值thin_pool_autoextend_threshold 80 thin_pool_autoextend_percent 20意思是池的使用率达到80%时自动给池追加当前池大小20%的容量。这个机制不配置好建议不要直接上生产环境。另外精简卷不支持缩容创建时虚拟容量想清楚再填这也是精简池最常见的埋点。5. 常见问题与故障排查实录5.1 忘了密码要进rd.breakLVM卷组怎么激活这个场景网上问得特别多很多老鸟第一次遇到也容易卡住。当一台OpenEuler机器忘了本机密码常规做法是重启后在GRUB菜单里按 e 编辑启动项找到 linux 开头的行在行尾加一个参数 rd.break然后按 CtrlX 启动系统会进入一个紧急shell。此时根文件系统被只读挂载在 /sysroot可别以为LVM已经万事大吉。在紧急shell里系统只完成了最小启动流程其他数据卷组大概率没有主动激活哪怕根卷组因为挂载 /sysroot 已经被initramfs碰过为了接下来能对整套系统做操作我仍然建议先手动确认LVM状态。执行mount -o remount,rw /sysroot lvm vgscan lvm vgchange -a yvgscan 先在磁盘上扫描出所有卷组vgchange -a y 把所有卷组标记为激活。激活之后 /dev/mapper 下才会出现 openeuler-root 这些设备后续 chroot /sysroot 进去才能正常操作系统。完整流程大概是mount -o remount,rw /sysroot lvm vgscan lvm vgchange -a y chroot /sysroot passwd改完密码后如果系统开启了SELinux建议在chroot环境里执行 touch /.autorelabel重新标记一下安全上下文避免因为上下文异常导致重启后无法登录。最后执行 exit 退出紧急shell系统会继续完成启动。整个过程不要瞎敲命令尤其是 lvm vgchange -a y 的时候如果有多块盘一定要先确认操作的是哪一块VG别在数据盘上做出不可逆的操作。5.2 扩容后容量没变化、克隆机器起不来三个高频坑第一个坑是扩容后文件系统容量没变。前面已经反复提过lvextend 只是把LV变大了文件系统本身还维持旧状态必须执行 xfs_growfs 或 resize2fs。如果忘了这一步df -h 显示的结果肯定是没变的。第二个坑是XFS想缩容。XFS的设计决定了它只能扩不能缩。如果业务上确实需要缩容唯一靠谱的办法是备份数据、删除LV重新创建、恢复数据。千万别想着在线缩容XFS那是拿数据开玩笑。ext4虽然能缩但也必须先在卸载状态下用 resize2fs 把文件系统缩到小于目标LV大小再 lvreduce 缩减LV容量顺序反了一样会出问题。第三个坑是克隆虚拟机后VG UUID冲突。把一台装了OpenEuler的虚拟机复制出来开机后经常卡在LVM相关阶段报 Volume group openeuler not found 或者 duplicate VG name。原因是克隆机的物理盘里还保留了原始VG的UUID新机器上启动时LVM发现同一个VG有重复标识就不激活了。解决思路是给新机器的VG重新生成UUIDvgimportclone -n openeuler /dev/sdb或者更直接一些对未激活的VG执行vgchange -u VG名称执行后VG的UUID会重新生成就能正常激活了。这个操作只影响LVM元数据不碰你的业务数据但操作前还是提醒一句先备份元数据vgexport / vgimport 这套流程比较复杂别在生产环境第一次实验。5.3 问题排查速查表我把LVM运维里最典型的几个问题和排查方向整理成一张表遇到问题对照着找思路现象可能原因处理办法df -h 容量没变LV扩展了但文件系统没调整xfs_growfs 挂载点或 resize2fs 设备路径vgs 看不到新盘磁盘还没有初始化成PV执行 pvcreate /dev/sdX新加磁盘 lsblk 不显示SCSI子系统没扫描到echo - - - /sys/class/scsi_host/host0/scan报 Volume group not foundVG名写错或卷组未激活vgscan 后 vgchange -a y快照空间写满导致源LV异常快照分配太小、写入量过大检查 Data%删除无用快照释放空间克隆虚拟机后无法启动VG UUID冲突vgimportclone 或 vgchange -u 重新生成UUID删除文件后空间不释放有进程仍占用已删除文件lsof | grep deleted重启对应进程这张表我贴在工位上很久了几乎每周都派上用场。6. 日常维护与监控技巧6.1 用一行脚本盯住卷组剩余空间LVM最大的风险往往不是操作失败而是无人注意的持续增长。日志、临时文件、数据库归档哪一天突然把卷组空间耗尽所有写入全部失败那才是灾难。所以监控卷组剩余空间应该像监控CPU和内存一样日常。我习惯写一个简单的脚本 /opt/lvm_check.sh#!/bin/bash threshold10 free$(vgs --noheadings --nosuffix --units g -o vg_free openeuler 2/dev/null | awk {print int($1)}) if [ $free -lt $threshold ]; then echo $(date) VG openeuler free space is ${free}G, below ${threshold}G /var/log/lvm_check.log fi脚本里 vgs 的 --units g 会强制按G输出--nosuffix 去掉单位awk 取整比较即可。写完后记得 chmod x /opt/lvm_check.sh然后加到crontab里crontab -e加一行0 9 * * * /opt/lvm_check.sh每天早上9点跑一次。空间告急时除了日志你还可以把它改成发送告警邮件或者调用接口通知。核心是把空间剩余多少从一个手工查看的事情变成一个系统自动关心的事情。6.2 让精简池和快照自动扩展别把预警拖成故障精简池的自动扩展配置在 /etc/lvm/lvm.conf 里原理前面已经说了。这里再补充一个日常观察命令定期看池和快照的占用比例比等告警更可靠lvs -o lv_name,data_percent,snap_percentdata_percent 表示精简池或卷的数据占用比例snap_percent 表示快照空间占用比例。我通常会在 cron 脚本里把这两个值也带入判断任何一个超过85%就先手工扩容或清理而不是干等自动扩展。自动扩展是兜底主动观测才是第一道防线。还有一个细节值得留意创建LV时考虑PE大小。默认PE是4MB存储量比较大的服务器VG容量达到几十TB时PE数量会非常巨大可能导致部分操作变慢。对这种场景可以在 vgcreate 时用 -s 参数指定更大的PE比如sudo vgcreate -s 16M data_vg /dev/sdbPE越大管理开销越小但空间分配粒度也会变粗LV大小会按16M的整数倍向上取整。小容量环境没必要改大容量环境值得规划一下。最后再分享一个我自己的习惯。动手折腾LVM这几年我最大的体会是LVM不复杂但它多了一层抽象要求你有更强的全局感。操作之前先看vgs确认卷组还有多少余量操作之后一定要确认文件系统真的感知到了新空间这两步抓住了九成故障都能避免。记得有次给 /home 扩容命令里卷组名写对了LV路径却不小心写成了 /dev/openeuler/root结果 lvextend -r 直接把 root 给撑大了重启后 /home 还是满的。从那以后我做任何LVM变更都先 lvs 把目标LV的路径原样复制出来再粘贴到命令里绝不再手工输入。这套流程我用到现在一次扩容事故都没再出过你也试试