CentOS 7 LVM实战:从原理到扩容缩容,一文搞定磁盘管理

📅 发布时间:2026/10/17 20:28:25
CentOS 7 LVM实战:从原理到扩容缩容,一文搞定磁盘管理
搞Linux运维的人应该都有这种体验CentOS 7安装器默认就会用LVM分区装系统的时候一路下一步等到服务器跑了两三年根分区被日志和容器镜像撑满了才反应过来——当初如果不懂LVM扩容只能靠重装系统或者多插一块盘做软链接把数据搬出去但只要你把LVM那套结构弄明白了其实三条命令就能在线把新磁盘空间“搬”进根分区数据不用动服务不用停。这篇文章就围绕CentOS 7的LVM分区把LVM的核心原理、安装时的分区规划、运维中最常用的扩容缩容操作以及我这些年踩过的坑一并整理出来。不管你是刚入门的新手还是早就用过但偶尔被xfs缩容坑一把的老手应该都能从里面捞到点实在的东西。1. 先弄明白LVM的三层结构1.1 为什么传统分区不够用传统分区方式是把一块磁盘切成若干个独立分区每个分区对应一个挂载点分区大小在建立的时候就固定了。问题在于切完之后想改大小非常麻烦尤其是我刚工作那几年经常遇到某个分区快满了、另一个分区却剩下几十G闲置的情况。想腾挪空间只能备份数据、删分区、重新划分、再恢复数据一套操作下来半夜两点都在机房喝咖啡。LVMLogical Volume Manager把磁盘空间从“固定分区”变成了“可拆组的积木”。它是在内核层面加了一层抽象让文件系统不再直接面对物理磁盘分区而是面对一个可以随时调整大小的逻辑卷。空间不够就把新的磁盘或分区加进这个池子然后把池子里的空间划给某个逻辑卷整个过程可以在线完成不需要卸载文件系统。这个特性对生产服务器来说太重要了尤其是数据库、日志这类增长不可控的业务。1.2 PV、VG、LV和PE一张图讲清楚LVM里有四个核心概念我用大白话拆一遍PVPhysical Volume物理卷把一块磁盘或一个磁盘分区初始化成PVLVM才能管理和使用它。你可以对整块盘做PV也可以对一个分区做PV。VGVolume Group卷组一个或多个PV组合在一起形成一个统一的存储池子。VG就是那个“大池子”所有空间都汇总在这里。LVLogical Volume逻辑卷从VG池子里划分出来的一个块我们给它格式化、挂载像使用普通分区一样使用它。PEPhysical Extent物理扩展块VG分配空间的最小单位CentOS 7默认PE大小是4MiB。LV的每一次扩容或缩容都是PE的整数倍。用仓库来类比PV是仓库的一堵堵墙VG是整个仓库的使用面积LV是在仓库里隔出来的一个房间。房间大小不需要跟墙皮完全对应你可以随时拆掉一面墙扩大房间也可以在房间中间加一道临时隔断缩小它。这就是LVM灵活性的来源。1.3 CentOS 7默认的LVM布局长什么样CentOS 7默认安装时如果选择了自动分区安装器会帮我们创建如下结构/dev/sda1通常是1G的/boot分区采用普通分区方式不是LVM。/dev/sda2标记为“Linux LVM”类型占掉磁盘剩余所有空间成为LVM的PV。安装器会基于这个PV创建一个名为centos的VG在CentOS 8/9上VG名变成了cl。在这个VG里默认创建三个LVroot、swap、home挂载点分别是/、swap和/home。用lsblk命令看下来大致长这样[rootlocalhost ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 200G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 199G 0 part ├─centos-root 253:0 0 50G 0 lvm / ├─centos-swap 253:1 0 4G 0 lvm [SWAP] └─centos-home 253:2 0 145G 0 lvm /home很多刚接触LVM的人会在这里犯迷糊为什么/不是直接挂在分区上而是挂在centos-root上因为/挂载点对应的实际上是一个逻辑卷逻辑卷通过内核的设备映射器device mapper映射到物理磁盘上。这个设计决定了它可以在线调整大小。1.4 为什么/boot不放进LVM有人会问既然LVM这么好为什么/boot还要单独用普通分区原因主要有两个引导器的兼容性GRUB等引导程序在系统启动阶段需要读取/boot目录下的内核和initramfs文件。虽然现代GRUB2理论上支持从LVM逻辑卷引导但普通分区是最成熟、最不会出问题的方案。安装器这么做是为了把启动失败的风险降到最低。故障域隔离LVM涉及多层映射一旦VG元数据损坏或者LV激活失败系统可能无法正常启动。/boot独立出来至少保证引导过程不依赖LVM出了问题还能通过救援模式修。所以我的建议是除非你很清楚自己在干什么否则永远不要动系统的/boot分区也不要试图把它并进LVM。1.5 什么时候该用LVM什么时候不该用LVM适合服务器场景尤其是这几类日志服务、监控系统磁盘空间增长不可预知数据库服务器需要根据数据增长持续扩容虚拟机宿主机经常要动态调整虚拟机磁盘大小。LVM不太适合的场景个人电脑日常使用空间需求变化小LVM反而多一层复杂度单块小容量磁盘比如32G的U盘LVM的灵活优势体现不出来还可能导致分区结构复杂对性能有极端要求的场景LVM会有轻微的性能损耗虽然现代硬件上基本感知不到。选型原则很简单生产环境有动态扩容需求用LVM没有这个需求普通分区也够用别为了“显得专业”去引入复杂性。2. 安装CentOS 7时LVM分区规划怎么做2.1 安装器里的自定义分区步骤安装CentOS 7时在“安装信息摘要”页面进入“安装位置”选择目标磁盘后点击“自定义分区配置”。接下来的操作顺序是为新系统创建/boot分区设备类型选择“标准分区”大小建议1G。创建/和/home挂载点时设备类型选择“LVM”大小为LVM设备分配初始空间。创建swap时设备类型同样选“LVM”。安装器会提示“将自动创建LVM卷组”默认VG名为centos点击“修改”可以设置VG名和PE大小。如果磁盘空间有富余也可以在点击“修改”的界面里勾选“创建空间不足时自动缩容”让安装器自己把剩余空间全部塞进VG。注意一个细节安装界面里给/分配的大小其实是分配给逻辑卷root的初始大小而不是这个LV的硬上限。只要VG里还有剩余空间以后想扩随时能扩。所以安装时不需要把空间一次性全给/但也不建议把/分得太小否则系统跑起来空间告急再扩虽然技术上可行但操作总是有风险。2.2 一套比较稳的分区规划参考以一个200G的系统盘为例我的推荐方案是挂载点/用途文件系统大小说明/bootxfs1G普通分区放内核和引导文件不建议动/xfs150GLVM系统根目录日志、软件、数据都有余量/homexfs0G或20GLVM如果机器是纯服务器不建议单独分homeswapswap4G~8GLVM按物理内存大小一般给内存的1~2倍这里有个很多新手会踩的坑CentOS 7安装器默认创建/home而且会瓜分掉磁盘一大半空间。如果这台机器是做服务器用用户根本不会登录图形界面/home常年空置而/反而空间不足。所以我的习惯是装服务器时干脆不创建/home把所有可用空间都划给/以后真需要单独挂载点再用LVM动态创建。如果初始分区分错了别急后面第4章会有重新分配/home空间的完整操作。2.3 解释一个设计PE大小到底该怎么选PE默认4MiB对应VG最大空间上限大约是256GB65534个PE乘以4MiB。如果你规划的总容量超过256G安装器或者vgcreate时就需要指定更大的PE。比如vgcreate -s 8M vg_data /dev/sdb1PE大小会影响一个逻辑卷的最大容量和空间分配粒度。PE越大单个LV可以做大但空间碎片的可能也越大PE越小空间利用率越高但LV容量上限越低。在CentOS 7的实际运维中如果不做超大规模存储默认4M完全够用我从来没去动过这个值。3. 已有系统上的LVM管理实操3.1 环境检查与工具确认不管哪个场景核心命令都来自lvm2这个软件包CentOS 7默认是装好的。万一命令不存在先装yum install -y lvm2 xfsprogs然后看一下当前的LVM状态pvs # 查看PV物理卷 vgs # 查看VG卷组 lvs # 查看LV逻辑卷 pvscan # 扫描并列出所有PV vgdisplay centos以我手上一台模拟环境为例输出如下[rootlocalhost ~]# pvs PV VG Fmt Attr PSize PFree /dev/sda2 centos lvm2 a-- 199.00g 8.00g [rootlocalhost ~]# vgs VG #PV #LV #SN Attr VSize VFree centos 1 3 0 wz--n- 199.00g 8.00g [rootlocalhost ~]# lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert root centos -wi-ao---- 50.00g home centos -wi-ao---- 145.00g swap centos -wi-ao---- 4.00g从输出里可以清楚看到目前VG里还剩8G可用空间没有分配。这就是后续扩容的“余粮”。3.2 新增磁盘并创建PV的完整流程现在假定虚拟化平台给这台机器新增了一块100G的磁盘在系统里显示为/dev/sdb。第一步先分区。[rootlocalhost ~]# fdisk /dev/sdbfdisk交互命令依次输入n # 新建分区 p # 选择主分区 1 # 分区号1 回车 # 起始扇区默认 回车 # 结束扇区默认用满整块盘 t # 改变分区类型 8e # Linux LVM类型 p # 预览分区表 w # 写入并退出如果磁盘容量超过2T推荐用parted做GPT分区用fdisk的话需要手动选GPT模式。分区完成后执行partprobe /dev/sdb让内核重新读取分区表再用lsblk确认新分区已经看到[rootlocalhost ~]# lsblk /dev/sdb sdb 8:16 0 100G 0 disk └─sdb1 8:17 0 100G 0 part其实也可以直接用整块盘做PVpvcreate /dev/sdb但我的习惯还是先分区。原因有几个分区表里能看到明确的LVM标记以后交接给别人时更容易看懂某些管理工具对“裸盘PV”识别不友好万一后续想移除其中一部分空间有分区表更容易操作。创建PV并纳入VGpvcreate /dev/sdb1 vgextend centos /dev/sdb1执行后vgs可以看到VG总容量从199G变成了299Gpvs也能看到新PV的归属和剩余空间。到这一步池子已经变大了但还没有给任何LV扩容所以df -h暂时不会看到任何变化。3.3 从VG里创建新逻辑卷并挂载如果新增空间不是要给根分区而是要给某个业务单独使用就需要在VG里创建新LV。例如创建一个80G的LVlvcreate -L 80G -n lv_data vg_data注意-n指定LV名称-L指定大小。创建完成后格式化和挂载mkfs.xfs /dev/vg_data/lv_data mkdir /data mount /dev/vg_data/lv_data /data这样/data就是一个全新的、可用的存储挂载点。如果后续想把这个LV扩到100G只需要在线执行lvextend -L 100G /dev/vg_data/lv_data xfs_growfs /data全程不需要卸载业务无感知。这就是LVM最吸引人的地方。3.4 为什么很多教程建议用UUID写fstab如果希望重启后依然自动挂载需要写入/etc/fstab。最稳妥的方式是使用文件系统的UUID而不是设备路径。通过blkid命令查看UUID[rootlocalhost ~]# blkid /dev/vg_data/lv_data /dev/vg_data/lv_data: UUID12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx TYPExfs然后追加一行UUID12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data xfs defaults 0 0为什么不建议直接写/dev/mapper/vg_data-lv_data因为设备路径在某些场景下比如系统重启后磁盘顺序变化、VG元数据恢复可能发生变更而UUID是文件系统创建时生成的全球唯一标识基本不可能冲突。不过一般来说控制器顺序不会乱/dev/mapper/vg-lv路径也是可以接受的如果是云环境更推荐UUID因为云盘挂载顺序真的会因为热插拔而变化。改完fstab建议先执行mount -a测试再重启验证。别等重启之后发现挂载失败才排查那样可能已经来不及登录进系统了。4. 核心场景动态扩容与缩容实战4.1 场景一用新增磁盘扩容根逻辑卷这是生产环境最典型的场景。根分区快满了新加了100G磁盘到系统。完整操作链路是这样的新盘分区→创建PV→扩VG→扩LV→扩文件系统。# 1. 分区设成8e fdisk /dev/sdb partprobe /dev/sdb # 2. 创建PV并入VG pvcreate /dev/sdb1 vgextend centos /dev/sdb1 # 3. 扩LV把VG里所有剩余空间都给root lvextend -l 100%FREE /dev/mapper/centos-root # 4. 扩文件系统xfs在线扩大 xfs_growfs / # 5. 验证 df -h这里有个非常关键的点也是很多人第一次操作时一脸懵的地方lvextend只扩了逻辑卷的容量文件系统不会自动跟着变大。所以必须再执行xfs_growfs /或者resize2fs让文件系统感知到LV的新大小。用xfs还是ext4取决于你初始格式化时的选择。CentOS 7默认是xfs所以上面用的xfs_growfs它直接接收“挂载点”作为参数。如果你当初选的是ext4那么扩大文件系统要用resize2fs /dev/mapper/centos-root注意resize2fs接收的是块设备路径不是挂载点。这个区别记清楚能省掉不少排查时间。4.2 场景二把/home的空间挪给根分区我见过太多机器装系统时默认创建了很大的/home结果业务根本不用/反而天天报警。这里复盘一个真实操作原VG布局是root 20G、home 100G目标是把home缩到10G剩下的90G全给root。核心难点是home分区默认是xfs文件系统而xfs不支持缩容。操作思路就是“备份→删掉LV→重建小LV→恢复数据→扩容root”。# 1. 备份home数据 tar czvf /tmp/home_bak.tar.gz /home # 2. 卸载home umount /home # 3. 删除原home LV lvremove /dev/mapper/centos-home # 4. 重建一个10G的home LV lvcreate -L 10G -n home centos mkfs.xfs /dev/mapper/centos-home # 5. 恢复数据如果是空home这步可跳过 tar xzvf /tmp/home_bak.tar.gz -C /home # 6. 把VG剩余空间全给root lvextend -l 100%FREE /dev/mapper/centos-root xfs_growfs / # 7. 把home挂上 mount /home操作顺序非常重要必须先备份、先缩home扩root放最后。如果先执行lvextend -l 100%FREEVG里所有剩余空间会被root吃掉后面就没空间重建home了。卸载home时如果提示target is busy说明有进程占用用fuser -km /home踢掉占用进程后再卸载。生产环境记得先确认业务方是否在用。4.3 场景三swap逻辑卷扩容swap如果也是LVM逻辑卷扩容同样在线化。在CentOS 7上默认/dev/mapper/centos-swap就是LVM。操作流程# 1. 查看当前状态 free -h swapon --show # 2. 关闭swap swapoff /dev/mapper/centos-swap # 3. 扩大LV比如增加4G lvextend -L 4G /dev/mapper/centos-swap # 4. 重新初始化swap文件系统 mkswap /dev/mapper/centos-swap # 5. 重新开启 swapon /dev/mapper/centos-swap # 6. 验证 free -h这里有个容易误解的地方mkswap会格式化swap区域相当于清空了原有交换区的内容。但swap本来就是内存的“缓存”断电即失所以清空没有数据损失的风险不需要备份。4.4 缩容的禁忌与ext4缩容流程LVM扩容容易缩容没那么简单主要是因为文件系统层面对缩容的限制。先说xfs。xfs文件系统从设计上就只支持扩大不支持缩小。哪怕你把LV用lvreduce减少了xfs_growfs也会直接报错因为xfs根本无法感知“缩小”强行缩只能损坏数据。所以对xfs想缩只能“删掉重建”也就是第4.2节用的办法。再说ext4。ext4支持在离线状态下缩小文件系统但顺序极其反直觉先缩小文件系统再缩小LV跟扩容顺序相反。# 1. 卸载 umount /dev/mapper/vg_data-lv_data # 2. 检查文件系统 e2fsck -f /dev/mapper/vg_data-lv_data # 3. 把文件系统缩到目标大小比如50G resize2fs /dev/mapper/vg_data-lv_data 50G # 4. 再把LV缩到合适大小比文件系统略大一点 lvreduce -L 52G /dev/mapper/vg_data-lv_data # 5. 重新检查并挂载 e2fsck -f /dev/mapper/vg_data-lv_data mount /dev/mapper/vg_data-lv_data /data顺序错了会怎样如果先lvreduce再resize2fs逻辑卷已经变小但文件系统元数据还认为它有更大空间一旦文件系统使用超过新的LV容量整个文件系统会损坏数据基本救不回来。所以缩容永远记得要么删了重建要么严格按“文件系统在前、LV在后”的顺序。5. 常见报错与运维笔记5.1 刚刚创建的LV报“设备不存在”新创建的LV访问/dev/vg_data/lv_data提示No such file or directory大概率是设备映射缓存还没刷新。解决办法vgscan vgchange -ayvgscan是扫描VG元数据vgchange -ay是激活所有活动VG。执行后再看/dev/mapper/下就有了。有时候lvcreate执行后一会儿消失不见也是这个原因。5.2 lvextend之后df显示容量没变化这是扩容操作中最最常见的疑惑。前面提过lvextend只是让LV变大了文件系统没有同步。xfs就执行xfs_growfs /挂载点ext4就执行resize2fs /dev/mapper/vg-lv。执行完再df -h容量才会刷新。顺便说一句xfs_growfs不管LV扩了多少只要直接执行就行它会自动扩展到LV当前的实际大小而resize2fs如果不带参数也会自动扩展到LV全部空间。5.3 umount提示device is busy一般是某个进程还留在该挂载点的工作目录下面比如你之前cd进去过。先fuser -km /home该命令会终止占用/home的进程。生产环境要小心建议先lsof | grep /home确认占用对象再决定是否强杀。如果只是自己的shell卡在里面cd /离开就行。5.4 误删了LV或VG数据能否恢复先说结论PV和VG的元数据还有一定恢复可能但LV一旦被lvremove恢复难度非常大基本得靠备份。误删VG后U盘救援模式里先用pvscan看PV是否还在。只要PV还在可以用vgcfgrestore恢复VG元数据再vgchange -ay激活。这个操作成功率高前提是你知道原来VG的名字。误删LV就比较麻烦了底层数据可能还在磁盘上但需要手动重建同样大小的LV才能尝试找回来还要祈祷没有新写入覆盖。所以我给所有朋友的建议都是高危操作前先做备份。对于LVM性价比最高的保护手段是快照。LVM快照不是备份但很适合做“后悔药”lvcreate -s -L 10G -n snap_root /dev/mapper/centos-root mount /dev/mapper/centos-snap_root /mnt-s表示创建快照-L 10G指定快照容量。快照会记录LV在某一时刻的数据状态数据变更时占用快照空间。如果操作出错可以直接从快照恢复。快照空间用满的话快照会失效所以不要长期保留操作完尽快删除用lvremove删除快照。5.5 一份LVM日常维护的避坑清单最后把零散经验整理成几条都是实打实的教训操作禁忌正确做法扩容任何LV只扩LV不扩文件系统xfs执行xfs_growfsext4执行resize2fs缩容xfs分区试图在线缩容xfs备份→删除LV→重建小LV→恢复缩容ext4分区先缩LV再缩文件系统先umountresize2fs再lvreduce写fstab用裸设备名如/dev/sda优先UUID其次/dev/mapper/vg-lv扩rootlvextend占了全部空间后面没余量先想好其他LV是否需要预留空间做快照长期保留、空间不足用完即删操作前创建我个人在实际操作中的体会是LVM真正解决了“磁盘空间不够用又不想停机”的问题但它的灵活性也要求更高的纪律性操作前看一遍vgs确认VG剩余空间扩LV之前想清楚文件系统类型缩容之前做好备份。把这几条养成习惯CentOS 7的LVM分区基本就再也不会出幺蛾子了。如果以后业务量继续涨还可以在这个基础上研究thin provision和跨主机集群方案那是另一篇故事了。