☰
LVM磁盘扩容实操指南:从分区识别到文件系统在线扩展,附踩坑记录
2026/10/23 1:33:37 网站建设 项目流程

前阵子帮某公司的一台内部机器扩容磁盘,折腾了一圈LVM,从查看分区状态、加物理卷,到扩展逻辑卷、在线调整文件系统,过程不算复杂,但里面有几个细节很容易被忽略。尤其是第一次操作的人,很容易在“分区类型”或者“文件系统调整”这步卡住。这篇就当是一份带踩坑记录的实操笔记,把LVM扩容的完整链路和背后的原理拆开讲一遍。

1. LVM扩容之前,先搞清楚你的机器是什么分区布局

很多人一上来就执行lvresize或者lvextend,结果提示空间不足,或者扩完了df看不到变化。原因多半是没弄明白当前磁盘在LVM体系里处于哪个层级,以及哪一层缺空间。

LVM的完整链路是:物理磁盘或分区(PV)→ 卷组(VG)→ 逻辑卷(LV)→ 文件系统。扩容的本质就是逐层检查、逐层分配。操作顺序必须从底层往上层走:先保证PV有空间,再确认VG有剩余空间,最后扩LV并调整文件系统。

建议先跑一遍下面这组命令,把家底盘清楚:

lsblk df -hT pvs vgs lvs
  • lsblk看的是磁盘和分区的大小、挂载点,能直接看到你的根分区、数据盘在哪个物理盘上。
  • df -hT看的是文件系统当前使用率和类型。
  • pvs、vgs、lvs分别显示物理卷、卷组、逻辑卷的空间分配情况。

常见的几种场景是这样的:

  1. 物理磁盘本身还有未分配的空间,但VG没有将它纳入。
  2. 有多块物理盘,VG还有剩余空间,直接扩LV就行。
  3. 整块盘已经全部划给了某个分区,需要先对分区表动手术,把分区扩大,再让PV识别新空间。
  4. 机器是虚拟机,底层的虚拟磁盘大小变了,但操作系统里看到的还是旧大小。

这几种情况的操作路径完全不同。我这次遇到的就是第4种,底层磁盘从80G扩到了120G,但系统里lsblk看到的还是80G,需要先让系统重新识别磁盘的新容量,然后才谈得上LVM扩容。如果是物理机加了一块新硬盘,流程又是另一套。

另外有一点值得提:/boot分区一般不在LVM里,是个独立的小分区。如果你只是根分区满了,扩LVM就行;如果是/boot满了,那是另一码事,扩容方式和LVM完全不搭边。这也是很多人搞混的地方。判断方法很简单,df -h /boot看下类型,如果是xfs或ext4且不挂LVM,那就单独处理;如果输出里写着/dev/mapper/...,才走LVM扩容。

2. 底层磁盘扩容后,让系统识别新容量的几种手段

虚拟机的虚拟磁盘在管理界面扩容后,操作系统不会主动发现整块磁盘变大了。如果你用lsblk看到的还是老容量,说明系统还没感知到新空间。这时候不同环境有不同的处理方法。

2.1 最简单粗暴:重启

重启是最稳妥的方式,绝大多数Linux发行版在开机过程中会重新扫描所有磁盘设备,直接拿到新容量。代价是如果机器上有正在跑的业务,重启窗口需要协调。

2.2 在线刷新:针对常见的SCSI/SAS/VMware虚拟磁盘

通过echo强制触发SCSI设备的重新扫描,可以在不重启的情况下刷新磁盘容量。

echo 1 > /sys/class/scsi_disk/0:0:0:0/device/rescan

但注意,设备路径里的0:0:0:0不是固定的,要根据实际情况找到对应的scsi设备。用下面的命令逐一列出:

ls /sys/class/scsi_disk/

然后逐个尝试刷新。如果是VMware虚拟机,更常用的做法是用vmware-toolbox-cmd或通过重启guest OS来获得新磁盘,但实际在/sys路径下刷新(rescan)对大多数版本也能生效。

2.3 某些云厂商的裸金属/云盘场景

部分云平台的块存储扩容后,在操作系统内直接rescan通常能生效,最多再执行一条partprobe重读分区表。老一点的系统可能需要用hdparm -z /dev/sda来强制内核重读分区表。

这里我实际遇到的问题是:lsblk能看到变化,但/dev/sda整块盘new size已经到位,可用fdisk -l看分区表时,发现分区大小没变。这是正常的,因为分区表还停留在旧空间上,你需要把分区扩大之后,PV才能拿到新增的空间。

3. 分区扩容:fdisk与parted的实操与边界

当物理盘已经识别到新容量,且旧分区并没有占满整块盘的时候,就需要对分区本身下手。分两种情况,一种是分区表的最后一个分区需要扩展;另一种是中间某个分区,这种情况没法安全扩展,建议不要动,除非你愿意重新做数据盘。

3.1 fdisk方式操作流程

以/dev/sda为例,假设/dev/sda2是LVM所在分区,操作流程如下:

fdisk /dev/sda p # 打印分区表,记录起始扇区 d # 删除分区(注意:只删分区,不删数据) n # 新建分区 p # 主分区 2 # 保持原分区编号 起始扇区 # 必须填之前记录的起始扇区,不要直接回车 结束扇区 # 直接回车使用剩余全部空间 w # 写入分区表

很多人担心删除分区再重建会丢数据。实际上,LVM的元数据存在PV内部,也就是你分的那个分区里的数据块上,只要分区起始扇区保持一致,重建分区不会动到实际数据。但是起始扇区必须手动指定,千万不要用fdisk默认的起始位置,否则分区起点对不上,数据就真没了。

建议在删除分区之前,用fdisk -l或者parted /dev/sda unit s print把起始扇区精确记录下来,最好截图或者抄在小本本上。这一步错了,后面神仙难救。

写分区表后,执行:

partprobe /dev/sda

或者重启让内核重新读取分区表。可以用lsblk确认分区大小已经变成新容量。

3.2 parted方式操作

如果分区表是GPT格式,或者你更喜欢parted,流程是:

parted /dev/sda unit s print free resizepart 2 100% quit

resizepart是较新版本parted的特性,可以直接把分区扩展到100%(即磁盘剩余所有空间),前提也一样——确保起点不动。执行完同样跑partprobe。

3.3 某个关键细节:分区编号和分区类型

用fdisk删除重建分区时,系统有时候会提示“分区编号已存在(分区在内存中)”,这时候可以先w写一次分区表并partprobe,或者用parted的resizepart来绕过。另外,分区类型要保持8e(Linux LVM),如果新建分区时默认变成了83(Linux filesystem),后续PV识别不到会提示找不到分区。用t命令手动改成8e。

有一点我说下,很多文章会说“删除重建分区表有风险,建议备份”。这话没夸张,我见过有人操作完之后数据丢了,基本都是起始扇区填错。所以如果你对命令行不是特别熟,更稳妥的路子是:不动分区,直接把新磁盘做成PV加入VG。

4. 卷组和逻辑卷的扩容,其实是最爽的一步

分区调整好之后,PV、VG、LV这一层的操作相对简单,但命令的细微参数也值得展开。

4.1 让PV感知新空间

pvresize /dev/sda2

执行后,用pvs查看,PV的大小应该已经变为新容量。比如原来是80G,现在应该是120G。如果没变,大多是因为分区表重读没生效,先partprobe再试。

4.2 确认VG剩余空间

vgs

看VFree那一列的数值。如果VG没有剩余空间,那就要考虑把新磁盘做成PV后加入VG,或者扩容已有的PV(上面步骤已经做了)。

4.3 把新磁盘加入VG(如果是加盘方案)

假设新盘是/dev/sdb,直接:

pvcreate /dev/sdb vgextend 你的卷组名 /dev/sdb

注意:pvcreate会清空磁盘上的所有数据,操作前务必确认磁盘没有在用。有的服务器可能装的是数据盘不是系统盘,别把正在用的数据盘直接初始化了。判断方法用lsblk看挂载情况,没有挂载且确认没有业务写入,才能执行。

4.4 扩展LV

lvextend -l +100%FREE /dev/你的卷组名/你的逻辑卷名

-l +100%FREE表示把VG里剩余所有空间全部给这个LV。如果你只想给指定大小,比如加20G:

lvextend -L +20G /dev/你的卷组名/你的逻辑卷名

这里多说一句:-L +20G是增加20G,-L 20G是设置LV成20G。两者区别很大,写错了可能会导致LV被缩小,缩小的操作有严重风险。建议第一次操作的,直接检查现有大小后再动手。

4.5 确认LV结果

lvs

看看LV Size是否已经是目标容量。如果df -h看到的还是旧容量,那是文件系统没有同步,接着往下走。

5. 文件系统在线扩容:ext4与xfs的不同,别套错命令

扩充完LV,不等于文件系统就自动变大了。要让操作系统真正能用上新增空间,需要调整文件系统。这一步用错命令,轻则报错,重则文件系统受损。

5.1 先确认文件系统类型

用之前df -hT的输出,或者:

blkid /dev/你的卷组名/你的逻辑卷名

看到TYPE="ext4"就是ext4,TYPE="xfs"就是xfs。

5.2 ext4文件系统的扩容命令

resize2fs /dev/你的卷组名/你的逻辑卷名

该命令会自动把文件系统扩展到整个LV。在线扩容是安全的,不用卸载。

5.3 xfs文件系统的扩容命令

xfs_growfs /挂载点

注意,xfs_growfs用的是挂载点,不是设备路径。比如:

xfs_growfs /

和ext4不同,xfs不支持缩小,只支持扩大。想缩小xfs文件系统?没有这个操作,除非备份重做。这一点在分区规划时就要想清楚。

5.4 某些特殊情况:文件系统在LV上但用的是btrfs

如果你用的是btrfs,命令又不一样:

btrfs filesystem resize max /挂载点

不过这种情况在普通服务器上比较少见,这里就不展开太多。只要记住一点:文件系统类型不同,扩容命令几乎完全不同。最稳妥的方法就是用blkid确认类型后再选命令。

5.5 扩完文件系统后df的验证

df -hT

看到Size那一列变大,才算真正完成。我和某位同事搭档处理过一台机器,扩LV时忘了文件系统这步,业务方反馈df没变化,后来一查才发现LV已经400G了,根文件系统还停留在200G,经典的二段跳问题。

6. 从pvs看到PV unchanged开始的完整排查链路

这里分享一下我这次的实际操作过程,因为正好覆盖了“系统里看不到新空间”到“df最终正常”的完整链路。这台机器是某公司的测试环境,虚拟机磁盘从80G扩到120G,根分区是/dev/mapper/centos-root,VG名是centos。

我第一次跑pvs的时候,PV还是80G。lsblk显示sda的大小已经是120G,说明虚拟机层面的磁盘扩容生效了。但sda2分区的大小还是80G,分区表没有同步。

执行partprobe /dev/sda之后,重新看lsblk,sda2还是80G。这种时候不用慌,说明内核还没完全接受新的分区表或者设备已经处于busy状态。重启我是不想重启的,因为上面有服务在跑,所以采用下面的方式:

parted /dev/sda unit s print

记录sda2的Start值。然后直接:

parted /dev/sda resizepart 2 100%

执行完,parted可能会提示老内核还在使用分区表,要求重启或者重新读取。这时跑partprobe /dev/sda,再用lsblk,发现sda2已经变成120G左右。

接下来按照前面说的流程:

pvresize /dev/sda2 pvs

PV已经显示120G。继续:

vgs

VFree那一列有40G。执行:

lvextend -l +100%FREE /dev/centos/root

然后确认文件系统类型:

blkid /dev/centos/root

是xfs,于是执行:

xfs_growfs /

跑完df -hT,根分区已经变成115G左右(扣掉部分系统保留空间)。

整个链路不算复杂,但每一步都可能出现“看起来没生效”的假象。如果卡住了,优先看是什么层没同步:磁盘层、分区层、PV层,还是LV层。逐层用lsblk、fdisk -l、pvs、vgs、lvs,就能定位卡点。

7. 扩容之后,我建议顺手检查的几件事

扩容完成后,不是df看到变大就万事大吉。有几个检查项是我每次都会顺手过一遍的,都很便宜,但对后续运维会有帮助。

7.1 LVM自检命令

vgscan vgck lvscan

检查卷组和逻辑卷的元数据是否健康。正常情况下输出里不会有“ERROR”或者“missing”。如果某个PV显示missing,说明可能有人在没通知的情况下把磁盘摘了,这种情况在虚拟化环境里不是没见过。

7.2 改开机自动挂载配置

现在的安装器大多会通过/etc/fstab里写/dev/mapper/centos-root这种设备路径,一般不会变化。但如果你修改过LV名或VG名,fstab对应关系会失联,开机可能直接进入emergency模式。检查一下fstab里的UUID或设备名是匹配的:

cat /etc/fstab blkid

不过依赖/dev/mapper/xx的方式在机器重启后也是稳定的,因为LVM的设备和顺序不会轻易变。

7.3 观察业务影响

扩容完成后,建议观察一段时间。你可以用iostat看一眼磁盘利用率,其实在线扩容对IO有一定影响,xfs_growfs和resize2fs都会触发元数据更新,极端情况下可能造成IO延迟增高。业务高峰期不建议做这种操作,最好在低峰期执行。这是我吃了好几次亏才养成的习惯。

7.4 顺手清理无用快照或旧LV

TMP空间、old log LV之类的,如果是在扩容过程中发现的陈年无用LV,在确认没有任何进程使用后可以顺手移除,但不要在扩容任务里顺手做。一次只做一件事,改存储尤其如此。

8. 几个反复遇到的坑:文件系统边界、PE大小和分区表

最后一个部分专门聊几个实际中反复被坑到的地方,希望后面看到文章的人能避开。

8.1 坑:删除重建分区起始位置变了

这是最高危的坑。fdisk重建分区时默认起始扇区可能和原分区不一致,一旦不一致数据全部无法识别。规避方式就是按老分区表手动填起始扇区,或者直接用parted的resizepart,不要自己重建分区。

如果实在没有记录老起始扇区,有一种办法:df命令看到的挂载关系在你删除分区前是正常的,但分区一删,必须立刻把原来的起始扇区写回来。如果你不确定自己能不能搞定,就别用这个方案,改为拉新盘来做VG扩容。稳妥比炫技重要。

8.2 坑:PV和VG的PE大小影响最小扩容粒度

LVM默认的PE大小通常是4MB,但如果你创建VG的时候改过PE大小,比如设成16MB或者64MB,逻辑卷扩容的最小粒度就是那个PE大小。假设VG的PE是64MB,你执行lvextend -L +100M,实际扩展的可能不是刚好100M,而是128M(2个PE)。这对一般场景没影响,但对需要精确控制容量的场景要注意。查看方法:

vgdisplay 你的卷组名 | grep "PE Size"

如果你在意这种细节,建议创建VG时统一用默认4MB,扩容的时候用-L +xxG而不是百分比,否则对齐问题会影响后续扩展的计算。

8.3 坑:lvextend命令里-l和-L的大小写/单位问题

-l是PE数量或者百分比,-L是容量。两者容易混。比如lvextend -l 100 /dev/vg/lv的意思是扩展到100个PE,而不是100%。如果你真想扩展到全部,写-l +100%FREE;如果固定容量,写-L +20G。这个错很隐蔽,尤其当你从文档里复制命令时,看漏一个符号,结果就完全不对。建议发命令前先看一遍lvs的当前容量,执行后再lvs确认。

8.4 坑:不是所有文件系统都能在线扩到LV的100%

ext4和xfs都能在线扩到LV的100%,但有些场景需要先卸载再扩容,比如某些特殊的网络文件系统或者非标准文件系统。普通场景下,ext4和xfs在线扩容都没问题。但如果文件系统已挂载且处于使用状态,扩容时内核会锁定数据结构,短时间内可能造成瞬时IO卡顿,量大的业务会感知到微小的延迟抖一下,体感不强但存在。大文件持续写入时做扩容,也可能让写延迟变大。所以如果有人跟你说“在线扩随便搞”,听听就好,真上生产还是挑低峰期。

8.5 坑:分区表是gpt还是dos,处理方式不同

在fdisk里o创建的是dos分区表,g创建的是gpt。gpt分区表情况下使用fdisk做删除重建,提示可能更严格,因为gpt每个分区有独立的GUID,直接d再n会生成新的GUID,虽然不影响LVM的PV识别,但对某些依赖分区GUID做标识的软件可能造成困扰。这种情况下,用parted的resizepart会保留分区GUID,更干净。

最后一点实际心得

说了这么多,LVM扩容本身真不是一个高难度操作,真正考验人的是对“分层”概念的理解。磁盘、分区、PV、VG、LV、文件系统,每一层都有自己独立的容量上限,哪一层满了都表现为“空间不够”。你只要掌握逐层检查、逐层扩展的顺序逻辑,不管以后遇到什么存储设备,都能按同样的思路去排查。

另外,如果你手头有重要的数据,扩容之前做一次备份或者快照始终是值得的。LVM本身支持在线做快照,虽然会占用VG的剩余空间,但关键时刻是个后悔药。我在生产环境动LVM之前,只要条件允许,都会先创建一个快照LV,扩完确认没问题再删除。这个习惯救过我一次,那次正好在删除重建分区时手一抖起始扇区填错,靠快照恢复了一部分数据,不至于酿成大事故。

如果你正在为扩容LVM分区发愁,希望这篇笔记能帮你少走几步弯路。有操作细节不清楚的,欢迎留言区讨论,我看到会回复。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询