我第一次被CentOS7 LVM分区救回来,是在一台跑着内部报表服务的机器上。数据盘当初图省事只分了一个主分区,用着用着空间见底,应用方又天天催着扩容量,只能选凌晨停机,用工具克隆分区再重挂,全程提心吊胆。后来所有新装的CentOS7系统,我都坚持在安装阶段就规划好LVM分区。可能有人觉得LVM是多余的一层抽象,但真正经历过磁盘满了之后在线扩容的人,往往一句话都不想争。这篇文章就把CentOS7上LVM分区的整个玩法——从安装规划、手动创建、在线扩容到快照恢复——串起来讲一遍,适合刚接手Linux服务器的人,也适合想给现有磁盘做一次“无痛体检”的老运维。
1. 先想清楚:为什么生产环境都抢着用LVM分区
1.1 普通分区的一次性困局
如果你用传统方式给硬盘分区,分完之后基本就是“一次定终身”。举个例子,一块500GB的硬盘,安装时把/分了30GB,/var分了50GB,剩下的全给了/home。半年后日志把/var塞满,但/home还剩200GB闲着,你该怎么办?传统办法是把某个分区数据搬走、删除分区、重新创建、再把数据搬回来,全程必须停机,而且搬家过程只要断电一下就是灾难现场。
更麻烦的是,如果当初分区表用的是MBR,一块超过2TB的盘还需要先转成GPT,分区工具、引导方式都要跟着动。哪怕只是扩充一个分区,也要动相邻的未分配空间,很多场景下根本找不到连续的空闲区域。这就是传统分区的核心痛点:磁盘空间被划分成不可变的小格子,资源调配极不灵活。
1.2 LVM到底帮你解决了什么
LVM的全称是Logical Volume Manager,它在物理磁盘和文件系统之间加了一层逻辑抽象。很多新手第一次看LVM概念会觉得绕,其实用仓库类比就很清楚:物理硬盘上的分区或整块硬盘,就像你买回来的货架(PV,物理卷);把这些货架统一放进一个仓库,就是卷组(VG);仓库里再根据实际需要划出一个个货架区域,叫逻辑卷(LV)。文件系统只看到逻辑卷,不关心底下的货架是从哪个仓库挪过来的,也不关心仓库是不是后来扩建过。
这种抽象换来的是三个实打实的好处。第一,空间可以跨磁盘:两块2TB的硬盘能并成一个逻辑卷,上层看到的不是两个分区,而是一个4TB的连续空间。第二,容量可以动态调整:逻辑卷能在线扩长,某些文件系统也能在线缩回,不需要重新分区。第三,出问题时有快照兜底:几秒钟拍个快照,升级软件、打补丁、改配置,翻车了还能原地还原。单凭这三点,就值得在CentOS7装系统时把所有数据分区放进LVM。
1.3 什么场景真的没必要用LVM
当然,LVM不是银弹。如果你是一台个人虚拟机,磁盘容量写死,系统装完也不会再做调整,那普通分区确实够用,少一层抽象还少一点维护点。某些对IO延迟极其敏感的数据库环境,如果团队对LVM不熟,也倾向于用直连分区,毕竟LVM本身虽然损耗极小,但排查IO问题时确实多了一个环节。另外,LVM适合“动态分配”这种长期诉求,如果你明确知道磁盘永远不会变,那刻意引入LVM反而是在给自己找活干。
我个人还有个经验:安装时不喜欢把系统盘所有分区全部塞进一个逻辑卷,至少/boot要独立出来,保留传统分区结构。原因后面会说,当前只要记住一个原则——系统盘和业务数据盘尽量分开管理,系统盘上的LVM布局越简单越好。
2. 安装CentOS7时的LVM分区规划与实操
2.1 图形安装界面里的手把手配置
CentOS7安装器里分区的入口很直观,在“安装信息摘要”界面点“安装位置”,然后选中磁盘,选择“我要配置分区”。此时最重要的是在左下方把分区方案从“标准分区”切换成“LVM”,CentOS7图形界面默认其实就是LVM方案,很多新手没注意就直接点完成了,这样装出来系统盘也是LVM,倒不算坏事。
选好LVM方案后,点击“+”添加挂载点。例如你要创建根分区,就在“挂载点”里选/,“期望容量”填20GB,“设备类型”选“LVM”。这时候安装器会自动生成一个卷组,默认名字在CentOS7里常是centos。继续添加/home、swap时,它们都会落入同一个卷组,只是划分成不同逻辑卷。值得注意的是,安装器有一个“+”旁边的小齿轮图标,点开可以设置卷组的名称、RAID级别和PE大小。生产环境我通常会把卷组名改成与用途相关,比如sys_vg,避免和默认值混在一起。
配置完之后点击“完成”,安装器会弹出“您已创建以下分区”的摘要,里面列出了挂载点、设备类型、物理卷、卷组、逻辑卷路径和容量。此时我建议认真核对一下逻辑卷路径,比如根分区通常是/dev/sys_vg/root,home是/dev/sys_vg/home。记住这个路径,后面很多命令都要用到。如果空间规划有误,趁安装还没开始,直接选中对应逻辑卷编辑即可,不用推倒重来。
2.2 BIOS和UEFI两种启动方式的布局差异
CentOS7横跨了从BIOS到UEFI过渡的历史阶段,分区规划上也必须分情况讨论。纯BIOS启动(Legacy模式)的机器,一般只需要一个普通分区当/boot,剩下的交给LVM即可。安装器会自动把/boot建为标准分区,通常是占用第一个分区,大小给到500MB到1GB,我很推荐给1GB,因为内核更新频繁时,旧内核不会永远自动清理,/boot一旦挤满,系统起不来是常事。
UEFI启动的机器则会多一个/boot/efi分区,这是EFI系统分区,必须是普通分区,推荐格式化为FAT32,容量建议200MB到600MB。此时/boot本身仍然可以是一个独立分区,而系统根目录、home、swap什么的继续走LVM。很多人安装时容易犯的错是手动把/boot/efi删掉或用LVM覆盖,这会导致安装完成后机器无法引导。除非你非常清楚UEFI引导细节,否则这两个分区都要按照安装器默认方案保留为普通分区。
2.3 安装阶段容量规划的建议
容量规划没有万能公式,我一般套用几档基础模板。最小生产环境:/给15GB,/home给20GB,/var给15GB,swap给4GB,剩余空间先不分配,留在卷组里当作机动容量。中等业务环境:/给30GB,/var给30GB,/home剩下全给,swap给内存大小的1到1.5倍。需要留意的是,CentOS7安装器常见的默认布局会用LVM包住根目录和swap,逻辑卷切得比较碎,后续想扩容某个目录,只要卷组还有剩余空间,lvextend就能直接把空间“匀”过去。
还有一条常被忽略的经验:在安装界面里,如果你预留了未分配空间,安装完成后卷组里会显示空余的PE。这在初始阶段看起来“浪费”,实际上非常有用。线上系统运行三个月后才开始增加业务数据,你再从卷组剩余空间划给/var,完全不需要重新分区、不需要停机,这就是LVM给运维的底气。
3. 手动创建一个LVM:从裸盘到逻辑卷全链路
3.1 LVM三层结构的工作逻辑
第二部分讲的是安装器帮你建LVM,很多人用了几年CentOS7,可能都没手动敲过一套完整的创建命令。但手动建LVM,才是理解整个机制最有效的路径。三层结构我再用一句话概括:pvcreate把磁盘变成PV,vgcreate把PV汇总成VG,lvcreate从VG里切出LV。文件系统最后落在LV上,所以一切动作都围绕这三个命令展开。
有个细节容易迷惑:物理卷可以直接建在整块磁盘上,也可以建在磁盘的分区上。生产环境我习惯直接用整块磁盘做PV,也就是/dev/sdb,少一层分区就少一层管理;但如果需要多块磁盘混用,或者考虑将来单块磁盘拆分成多个用途,先在磁盘上建分区再创建PV反而更清晰。两种方式都能被LVM识别,不必拘泥。
3.2 全流程操作实录
假设服务器加了一块新硬盘/dev/sdb,要把整块盘交给LVM,并最终挂载到/data目录。第一步先确认磁盘是否已经被系统识别:
lsblk # NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT # sdb 8:16 0 2T 0 disk确认是新盘且没有分区后,开始创建PV:
pvcreate /dev/sdb pvs # PV VG Fmt Attr PSize PFree # /dev/sdb lvm2 --- 2.00t 2.00t接着创建卷组。我把卷组命名为data_vg:
vgcreate data_vg /dev/sdb vgs # VG #PV #LV #SN Attr VSize VFree # data_vg 1 0 0 wz--n- 2.00t 2.00t再从卷组里切出一个200GB的逻辑卷,命名为data_lv:
lvcreate -L 200G -n data_lv data_vg lvs # LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert # data_lv data_vg -wi-a----- 200.00g到这里,LVM三层结构就搭好了,剩下的步骤和普通分区没区别。格式化逻辑卷,这里按CentOS7默认文件系统选XFS:
mkfs.xfs /dev/data_vg/data_lv mkdir -p /data mount /dev/data_vg/data_lv /data如果希望重启后自动挂载,写入/etc/fstab。这里强烈建议写UUID而不是设备路径,因为逻辑卷路径在数据盘重新排序后可能发生变化。用blkid /dev/data_vg/data_lv拿准确UUID,然后追加一行。
3.3 预留空间的妙用
上面的例子中,VG一共2TB,只用了200GB,意味着还有1.8TB留在卷组里。这时候你再去执行lvextend -L +20G /dev/data_vg/data_lv,扩出来的空间立刻就能被LV消费,而且全程不影响已有数据。
我通常会在创建LV时故意不把VG的空间用完,至少预留20%。这个习惯后来帮我避免了很多次“临时要扩容量,结果VG也满了,还得到处找盘”的尴尬。另外,创建VG时可以指定PE大小,比如vgcreate -s 16M data_vg /dev/sdb。PE是LVM分配空间的最小单位,默认4MB,一般不用改,但如果LV容量非常大,用大一点的PE能减少元数据开销,对性能基本没影响。
4. LVM在线扩缩容:服务器不重启的磁盘手术
4.1 卷组扩容:把新硬盘塞进仓库
业务增长的速度永远超预期。某天你执行df -h,发现/data已经用到92%,而VG剩余空间也见底了。此时如果还有一块空盘/dev/sdc,只需要两步就能让仓库变大:
pvcreate /dev/sdc vgextend data_vg /dev/sdc执行完vgs,你会发现VSize从2TB变成了4TB,VFree相应增长。卷组扩容不需要卸载文件系统,也不会中断业务,因为整个过程中LV和文件系统纹丝未动,只是仓库面积变大了。如果需要加入的磁盘不是整块盘,而是分区,也照样可以pvcreate /dev/sdc1,LVM并不挑剔物理载体。
4.2 逻辑卷扩容与文件系统扩展
卷组有了新空间,接下来就是把LV变大。最稳的顺序是:先扩LV,再扩文件系统。比如要给/data逻辑卷增加20GB:
lvextend -L +20G /dev/data_vg/data_lvLV扩完后,文件系统还停在原来的200GB,必须再执行对应扩容命令。XFS用xfs_growfs,且不需要卸载:
xfs_growfs /dataext4则用resize2fs:
resize2fs /dev/data_vg/data_lv其实新版LVM已经提供了-r参数,比如lvextend -r -L +20G,系统会自动检测文件系统类型并执行扩容,推荐日常使用。我见过不少新手只做lvextend,一看df -h容量没变就以为失败了,实际是忘了扩文件系统。记住一个口诀:df -h看文件系统,lvs/vgs看LVM层,两者增长的步调不一定同步。
4.3 缩减逻辑卷:xfs先别想了,ext4可以
LVM的广告词常说“在线扩缩容”,但缩的时候要分文件系统。CentOS7默认的XFS不支持缩减,只能只增不减。如果你发现/data分大了想收回来,XFS唯一的方案是:把数据备份出去、删除逻辑卷、按新大小重建、再把数据恢复回来,期间必然停机。这就是为什么初始规划时不能乱给XFS逻辑卷塞空间。
如果你当初用的文件系统是ext4,那确实能在卸载后缩减。以把一个120GB的ext4逻辑卷缩回100GB为例:
umount /data e2fsck -f /dev/data_vg/data_lv resize2fs /dev/data_vg/data_lv 100G lvreduce -L 100G /dev/data_vg/data_lv mount /data注意先缩文件系统,再缩LV,顺序反了会造成文件系统损坏。磁盘操作有风险,任何缩减动作前都应该留有备份。我个人的建议是:生产环境别把精力花在“缩”上,运维重点应该是保证“扩”足够顺滑,容量规划宁可多一点,也没人嫌磁盘大。
4.4 常见扩容失败场景:扩了个寂寞
扩容看起来就几条命令,实际翻车的场景不少。最典型的毛病是:lvextend成功了,VG也显示空间被分配走,但df -h没有变化。前面说了,这基本是忘记扩文件系统,可以确认一下当前LV大小和文件系统大小是否一致。另一个常见问题是在xfs_growfs时搞错了挂载点,命令写成了xfs_growfs /dev/data_vg/data_lv,而XFS要求传入挂载点路径,xfs_growfs /data才是正确写法。执行后输出会告诉你原来大小和当前大小,看到数值变化才算真的落地。
还有的人扩容LV时发现lvextend报“Insufficient free space”,但VG明明显示剩余空间不少。这种情况要检查VG里的PE是不是被其他LV占用了,尤其是有快照的时候,快照也吃空间。另一个隐蔽原因是逻辑卷开启了thin pool,可用空间的计算逻辑与普通LV不同。这时先lvs -a看看所有卷,再决定要不要删除临时快照释放空间。
5. 快照备份与误删恢复:LVM最后的退路
5.1 给系统做一次“后悔药”
升级内核、安装重大补丁、改数据库配置之前,我习惯先拍一个LVM快照。给/data逻辑卷创建快照很简单:
lvcreate -s -L 10G -n data_snap /dev/data_vg/data_lv-s表示snapshot,-L 10G是指快照容量,-n是快照名。命令执行完,再用lvs查看时会多出一行类型为inherit的快照卷。如果后续操作半小时,发现事情搞砸了,先把挂载点卸载,再把快照合并回原LV即可:
umount /data lvconvert --merge /dev/data_vg/data_snap mount /data合并完成后,快照卷消失,数据恢复到快照创建时点。这个流程在测试机上我演练过多次,操作顺序只要颠倒一次,就可能把原来的LV搞坏。所以我的铁律是:任何快照合并操作之前,先lsblk确认所有文件系统都已卸载,并且把当前原LV的状态记录下来。
5.2 快照为什么能瞬间完成
第一次看到快照秒建,很多人都会怀疑是不是哪儿写错了。其实LVM快照用的是写时复制技术:创建快照的瞬间,并不复制LV全量数据,而是把原卷的“地址索引”复制一份。此后原卷上发生写入的块,在覆盖前先把旧数据拷贝到快照区;快照里保留的就是从创建时点以来被修改过的旧块。换句话说,快照大小不完全等于数据量,而是接近“快照后这段时间里改动数据的总量”。
这解释了一个常见现象:快照建了20GB,但一晚上就满了。原因可能是该逻辑卷写入量巨大,改动过的数据块超过了快照预留空间。快照写满后不会自动变大,LVM会直接把快照标记为“溢出”并停止工作,继续写入甚至有坏卷风险。所以给快照分配空间时要估算,小需求给10GB没问题,但当日更新量超过10GB的业务,请直接把快照容量给到LV数据量的30%以上,或者建完快照尽快完成危险操作并删除快照。
5.3 逻辑卷误删的抢救实话实说
LVM给了快照这种“后悔药”,但很多人心存侥幸地去执行lvremove,误删根逻辑卷后想完全恢复,说实话难度极高。LVM在逻辑卷删除后会从VG中移除对应的LV元数据,如果是误删LV且还没对磁盘做新的写入,某些情况下可以用vgcfgrestore配合备份的元数据文件尝试找回。但这种方法极度依赖运气,找回的往往也是元数据,而不是完整可用的数据块。
我在实际运维中的态度是:把LVM快照当成唯一可靠的高速恢复手段,同时每天对关键数据做外部备份。真要遇到误删,先别慌着继续操作,立刻记录当前VG、PV状态,评估元数据备份文件是否有效。如果业务数据非常关键,优先从备份恢复整机或逻辑卷,别拿生产环境赌命。LVM不是备份系统,它只是给恢复多一层缓冲。
6. LVM日常运维里我踩过的一些坑
6.1 /boot要不要放进LVM
理论上CentOS7的引导加载器可以识别LVM上的/boot,但实际运维中我坚持把/boot放在普通分区。原因很现实:引导加载器对LVM的解析是额外的复杂度,一旦逻辑卷改名、缩小或快照合并出问题,最容易出现的就是机器起不来,而修复引导环境比修复数据分区麻烦得多。毕竟/boot容量需求很小,更新内核撑死了1GB,没必要用LVM的动态能力去换一个“可能有用的灵活”。安装器默认方案其实就是这样设计的,尊重默认方案往往是最省心的。
如果安装时没注意把/boot也放进了LVM卷组,后续维护会遇到一个典型场景:内核更新后无法启动,只能进救援模式重新配置引导。这时候再拆分/boot很不划算,所以新装机时一定要确认/boot和/boot/efi的设备类型是“标准分区”。
6.2 PE大小、VG名称和UUID的隐坑
LVM元数据里藏着一堆小陷阱,平时不碰没事,一碰就是坑。创建VG时如果指定过PE大小,后续往VG里加新PV,新PV向VG申请空间时会自动沿用VG的PE大小,但也可能出现边界对齐上的别扭。比较稳妥的做法是:所有PV在创建前都用分区对齐到1MB,再用vgcreate -s 4M保持默认,除非你知道自己在做什么。
VG名称也是常见冲突点。如果两台服务器都用默认卷组名centos,一旦把其中一块数据盘插到另一台机器上,系统可能因为两个VG同名而产生混乱。我管理的机器,卷组名一律按用途改,比如mysql_vg、data_vg,数据盘交换时一眼就能分辨。UUID的问题则更多出现在/etc/fstab里,逻辑卷路径可能因为VG重命名而改变,但UUID是稳定的,所以挂载配置我从来不写/dev/vg/lv,一律用blkid里的UUID。
6.3 SSD和LVM混用时的一些习惯
现在服务器基本是SSD起步,很多同学担心LVM那一层会影响性能。从我的实测看,正常IO路径下LVM带来的开销几乎可以忽略,瓶颈基本在磁盘本身或文件系统配置。SSD若担心TRIM问题,注意在挂载参数里启用discard,或者搭配定时fstrim任务。逻辑卷的底层物理块和文件系统块之间的映射本来就有,加上SSD也不是机械盘,不需要过分追求连续空间。
不过有一个习惯值得保留:不要把系统盘和数据盘塞进同一个VG。系统盘逻辑卷和业务数据逻辑卷混在一个卷组里,好处是空间灵活,坏处是某一侧把空间吃满,另一侧可能连日志都写不了。分区规划这件事,有时候不是技术问题,而是“给未来留余地”的问题。我见过太多临时把/扩到80GB,结果某天日志填满根分区导致服务雪崩的例子,这真不能怪LVM,只能怪规划时没把风险隔离开。
最后再分享一个小技巧:每次对LVM做动作前,先执行vgs --backup或直接备份/etc/lvm/backup下的元数据文件。这个习惯成本极低,但真到了需要靠vgcfgrestore救急的时候,你会感谢自己当初多敲了一条命令。