
如果你手头有一台 CentOS Stream 9 服务器某天突然收到根分区使用率 97% 的告警日志写不进去、服务开始报错、连 SSH 都卡顿而生产环境又不可能说重启就重启——这时候你需要的正是 LVM 在线扩容。基于 LVM 的逻辑卷管理CentOS Stream 9 的根分区可以在系统不重启、服务不停机的情况下直接扩大全程只需要几条命令。这篇教程就是我从实际运维里整理出来的完整流程从原理到命令、从判断到避坑全都写清楚了。操作步骤不复杂不需要多深的 Linux 功底第一次做扩容的运维新手可以照着敲抢修现场的技术同学也可以直接拿来当手册用。先说明一下教程里的命令我都按真实场景验证过示例环境里 VG 名是 cs、根 LV 路径是 /dev/cs/root但这只是我机器的命名。你机器上的 VG 名可能是 centos、rhel 或者其他什么一切以你自己的 vgs、lvs 输出为准不要照抄名字。1. 扩容前先理清三件事根分区为什么会满、LVM 凭什么能在线扩1.1 根分区写满的典型场景与后果根分区是 Linux 系统里最容易被塞满的地方而且往往是在你毫无防备的时候出问题。我接手过的故障里最常见的几种情况是业务日志和系统日志持续增长比如 /var/log 下的 messages、journal 文件没有配置轮转几天就能吃掉十几 GB。容器镜像和容器数据堆积Docker/containerd 的默认数据目录通常就在 /var/lib/docker 或 /var/lib/containers镜像拉多了、日志没清理空间很快就没了。内核更新和软件包缓存dnf 升级残留的旧内核、缓存包都占用 /boot 和 /usr 所在分区的空间。数据库、缓存文件直接写在根分区上比如 MySQL 的 datadir 没有单独规划盘随着业务增长把根分区填满。临时文件/tmp 下有程序异常生成的大文件文件被进程占用删不掉肉眼很难发现。根分区写满的后果不只是不能写文件这么简单。系统很多核心功能依赖 / 目录下的可写空间比如 /run 下的 socket 文件、/tmp 下的临时文件、/var 下的锁文件。一旦满了可能会出现进程崩溃、数据库拒绝写入、SSH 登录后无法创建历史记录文件、cron 任务静默失败等一堆看起来毫无关联的诡异问题。所以遇到根分区快满的时候最优解不是急着删文件你根本不知道哪些能删而是先把容量扩上去让系统恢复健康之后再从容地排查是什么吃掉了空间。1.2 LVM 的三层抽象PV、VG、LV 一次讲透想理解 LVM 在线扩容必须先把它的三层结构搞清楚。LVMLogical Volume Manager逻辑卷管理把磁盘管理分成了三层PVPhysical Volume物理卷可以是一块整盘也可以是一个分区。它就代表物理上真实存在的存储空间。VGVolume Group卷组由一块或多块 PV 组成的一个容量池。PV 可以随时加入 VG所以 VG 的容量可以动态变大。LVLogical Volume逻辑卷从 VG 这个容量池里划分出来的虚拟磁盘。系统真正格式化、挂载、写入数据的是 LV。根分区在 LVM 场景下就是一个 LV。用日常的东西类比PV 是你买回来的一桶桶水VG 是你家的蓄水池LV 是从水池接出来的一根水管。水池里的水可以随时从外面提桶加进来水管也可以随时换更粗的。对使用水的家电来说它只看到水管出口的出水量完全不知道水池扩容这件事——这就是在线扩容的神奇之处。CentOS Stream 9 默认安装的时候如果选的是自动分区方案根分区通常就在 LVM 上/boot 是独立分区根目录挂载在一个 LV 上。这也就意味着只要你当初没有手动改过分区方式大概率可以直接用 LVM 在线扩容。1.3 在线扩容的前提、边界与安全底线LVM 在线扩容不是所有场景都能用的动手之前要先确认三个前提根分区必须是由 LVM 管理的。怎么确认执行 lsblk如果根目录对应的设备路径是 /dev/mapper/xxx 或者 lvm 类型就说明是 LVM。如果根分区是普通分区比如 /dev/sda2 直接挂载到 /那这套流程用不了只能通过其他方式处理比如用 parted 调整分区风险更高或者迁移数据。要扩容的 LV 所在 VG 有足够的可用空间或者你有办法补充新磁盘、扩展原磁盘的容量。这是扩容的粮草。当前文件系统支持在线扩容。CentOS Stream 9 默认根分区是 XFSXFS 完全支持在线扩展如果是 ext4 也支持在线扩展。要注意的是XFS 只能扩大不能缩小所以扩容操作本身安全但千万不要想着用 LVM 缩小 XFS 根分区。安全底线方面我的习惯是任何磁盘操作之前先做一份云平台快照或者至少确认这台机器有最近的备份。lvextend 本身是相当安全、成熟的元数据操作但它毕竟是动底层存储的东西花几分钟打个快照能让你在操作失误时全身而退。另外操作尽量放在业务低峰期虽然在线扩容对服务影响很小但逻辑卷元数据和文件系统增长会有瞬时 IO 负载。2. 体检环节四组命令看清根分区的真实家底2.1 第一步先看清楚当前根分区的用量与挂载情况不管多急着扩容动手前都要先做一次体检。我通常按固定顺序跑以下几组命令首先看根分区的使用率和文件系统类型df -hT /这个命令的 T 参数很关键它会显示文件系统类型。输出里能看到挂载点是 / 的设备比如 /dev/mapper/cs-rootType 是 xfs。记住这个类型后面决定用哪个扩容命令。然后再看整体磁盘结构和挂载关系lsblklsblk 会以树形结构显示所有块设备。一个典型的输出长这样NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 60G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 59G 0 part └─cs-root 253:0 0 40G 0 lvm /看到 cs-root 这一行挂载在 /说明根分区确实是 LV。同时注意 sda2 分区大小是 59G而 LV root 只有 40G——也就是说卷组里很可能还有空闲空间这就是我们在线扩容的底气。2.2 LVM 家底盘点vgs、lvs、pvs 三个命令怎么读接下来用 LVM 自带的三个命令看家族明细vgs lvs pvs三个命令分别对应查看卷组、逻辑卷、物理卷的概况。输出示例# vgs VG #PV #LV #SN Attr VSize VFree cs 1 1 0 wz--n- 58.99g 19.00g # lvs LV VG Attr LSize Pool Origin Data% Meta% root cs -wi-ao---- 40.00g这里的 VFree 列是 19.00g表示卷组 cs 里还有 19GB 没分配的空间。你现在要做的判断很简单VFree 有空间直接给根 LV 扩容。VFree 是 0 或者不够用就需要先给 VG 增加容量见后面第 4 章。如果觉得 vgs 输出不够详细可以用 vgdisplay 看更完整的信息比如 PE 大小和空闲 PE 数量。vgdisplay cs里会看到 Free PE / Total PEPE 是 LVM 分配空间的最小单位默认一般是 4MiB。知道 PE 大小有助于理解 lvextend 用 -l 指定数量时的换算关系。2.3 判断扩容路径与文件系统类型避免选错命令体检做完其实已经把走哪条路想清楚了如果 lsblk 显示根分区是 LV 类型且 vgs 显示 VFree 有空间走直接扩 LV这条路对应第 3 章。如果 vgs 显示 VFree 已经耗尽但磁盘本身还有未分配空间比如 sda 是 100G但 sda2 分区只有 60G可以走扩展分区 pvresize这条路对应 4.2 节。如果机器上还有一块新加的空白磁盘走新盘建 PV 并入 VG这条路对应 4.1 节。文件系统类型决定了最后的 grow 命令CentOS Stream 9 默认是 XFS用 xfs_growfs如果当初手选成了 ext4用 resize2fs。用 lvextend -r 的话可以自动识别但手动操作时必须分清。一句话总结扩容的本质是先在 VG 层把水加够再在 LV 层把水管加粗最后让文件系统感知到新容量。每一步都有对应命令缺一不可。3. 主流程第一步VG 有富余时直接在线扩 LV3.1 推荐做法lvextend -r 一步完成 LV 与文件系统扩容体检确认 VG 还有 19G 空闲之后扩容命令其实就一行。先看根 LV 的名字比如 /dev/cs/root然后执行lvextend -r -l 100%FREE /dev/cs/root这条命令里-r 是 --resizefs 的简写含义是扩展逻辑卷之后自动扩展文件系统一步到位。-l 100%FREE 表示把卷组里所有剩余空闲空间全部分配给这个 LV。注意这个百分比是相对于 VG 的空闲空间不是 LV 当前大小。执行后你会看到类似这样的输出Size of logical volume cs/root changed from 40.00 GiB (10240 extents) to 59.00 GiB (15104 extents). Logical volume cs/root successfully resized. File system xfs found on cs/root, mounted at / File system size changed from 40.00 GiB to 59.00 GiB看到 File system size changed 这一行说明文件系统也自动扩展成功了。整个过程不需要重启也不需要卸载根分区服务全程在线。这就是 LVM 在线扩容最舒服的地方。如果你不想把 VG 里的空间全给根分区想留一点余量给后续建其他 LV 用可以改成指定增量大小比如lvextend -r -L 15G /dev/cs/root-L 后面跟的是具体大小15G 表示在原有基础上增加 15GBVG 里还会剩 4G 空间。习惯上我更推荐有明确容量需求时用 -L想快速救急时用 -l 100%FREE。3.2 手动路线lvextend 之后 xfs_growfs 与 resize2fs 该怎么选虽然 -r 参数很方便我还是要单独讲一下手动路线因为实际运维中你总会遇到 -r 不好使的时候比如宿主机 lvm2 版本较老、或者文件系统工具缺失。手动路线分两步。第一步同样扩 LVlvextend -L 19G /dev/cs/root注意这里不加 -rLV 扩容后文件系统大小不变。此时你执行 df -hT 会看到容量没有任何变化这是正常的因为文件系统还没有感知新空间。第二步根据文件系统类型选命令。前面 df -hT 已经确认了根分区是 XFS执行xfs_growfs /xfs_growfs 的参数是挂载点不是设备路径。对于根分区直接写 / 就够了。它会扫描挂载在 / 上的 XFS 文件系统并把容量扩展到设备实际大小输出里会出现data blocks changed from ... to ...看到这行就说明扩展生效。如果你当初把 / 做成了 ext4则用resize2fs /dev/cs/rootresize2fs 的参数是设备路径和 xfs_growfs 恰好相反。它同样支持在线扩展 ext4输出类似Resizing the filesystem on /dev/cs/root to 12345678 (4k) blocks.。新手最容易犯的错就是把命令和文件系统搞混XFS 用 resize2fs 会直接报错ext4 用 xfs_growfs 也会告诉你找不到 XFS 文件系统。所以每次扩容前用 df -hT / 看一眼类型几秒钟的事。3.3 扩容完成的验证与输出解读扩容不是执行完命令就收工验证环节必须做。我一般按下面的顺序确认df -hT / vgs lvsdf 看使用率降没降vgs 看 VFree 是否归零取决于你用了哪种扩容方式lvs 看 LV 新大小。还是用前面的例子扩容前后对比大概是这样检查项扩容前扩容后/ 文件系统大小40G59G/ 使用率98%66% 左右VG 空闲19G0如果用了 100%FREELV 大小40G59G如果 df 显示容量没变请回到 3.2 节手动执行 xfs_growfs / 或者 resize2fs。我见过很多同事扩完 LV 忘了扩文件系统隔天一脸懵地来问我为什么 lvextend 没生效其实命令本身没有任何问题。另外一个小细节执行 lvextend 时输出的 extents 数字是和 VG 的 PE 大小挂钩的。默认 PE 是 4MiB所以 1GB 大约是 256 个 PE。看到 10240 extents 对应 40GB、15104 extents 对应 59GB换算一下能帮你快速判断 LVM 元数据层面是否真的按预期分配了。4. VG 不够用了怎么办新增磁盘与云盘扩容两条路径4.1 新增数据盘并入 VG从识别磁盘到 vgextend 的完整命令链VFree 是 0 的时候第一步先让 VG 变大。最常见的做法是给机器加一块新磁盘把整块盘或盘上分区变成 PV再并入 VG。以云环境为例给实例新挂载一块 100G 数据盘后先确认系统识别到了lsblk如果看到类似 /dev/sdb 这样的新设备大小 100G且没有挂载点就可以直接拿它做 PV。我个人的偏好是云盘直接用整块盘做 PV不建分区表省事且性能无损。执行pvcreate /dev/sdb vgextend cs /dev/sdbpvcreate 是把这块盘变成物理卷。vgextend 是把它并入名为 cs 的卷组。成功后能看到Volume group cs successfully extended。再跑一遍 vgsVFree 应该多了 100G。如果你更习惯分区方式或者要加进 VG 的盘将来可能还有其他用途那就先进 fdisk 建分区fdisk /dev/sdb交互式操作里依次按 n新建分区、p主分区、回车分区号默认 1、回车两次扇区默认、t修改类型、输入 8eLinux LVM、w写入。之后刷新分区表并创建 PVpartprobe /dev/sdb pvcreate /dev/sdb1 vgextend cs /dev/sdb1整块盘和分区两种路径殊途同归最终效果都是给 VG 增加容量。之后回到第 3 章的 lvextend 流程把空间分给根分区即可。4.2 云控制台原地扩容系统盘growpart 配合 pvresize 的经典流程除了加新盘云环境里还有一种很常见的场景直接扩容已有系统盘。比如最初系统盘 60G你在控制台把它扩到了 200G。这种场景下磁盘设备不会变成新的 /dev/sdb而是 /dev/sda 本身变大但分区和 PV 还停留在原来的 60G 尺寸需要分三步把增量空间一层层认进来。第一步确认内核已经识别到新容量lsblk正常情况下 sda 会显示 200G但 sda1、sda2 分区还是原大小。如果 sda 都还是 60G说明内核还没刷新磁盘容量执行 4.3 里的 SCSI 扫描或重启。第二步扩展分区。假设根 PV 在 /dev/sda2 上先用 growpart 把分区扩到磁盘末尾dnf install -y cloud-utils-growpart growpart /dev/sda 2 partprobe /dev/sdagrowpart 后面第一个参数是磁盘设备第二个是分区号。运行结束后 sda2 分区会占满整个 sda 的剩余空间。第三步扩展 PVpvresize /dev/sda2pvresize 的作用是让 PV 使用扩容后的整个分区空间。执行完可以用 pvs 对比前后 Size。如果 PV 当初是直接建在整块盘上的比如 PV 就是 /dev/sda跳过 growpart直接执行 pvresize /dev/sda 即可。到这里 VG 的容量已经变大vgs 应该能看到 VSize 和 VFree 都增加了。剩下的老套路lvextend -r 或手动 xfs_growfs /。这套流程在阿里云这类云平台上是通用的。只要底层是 virtio 等虚拟化设备且系统引导没问题CentOS Stream 9 都能支持热扩容后在线完成上述操作。不同点只在于控制台触发扩容后内核刷新磁盘容量可能在几秒到几分钟内完成少数情况需要重启一次。4.3 新盘识别不出来时的排查顺序加新盘后 lsblk 看不到设备这是大家在云环境里问得最多的问题。我的排查顺序固定如下先看 /proc/partitionscat /proc/partitions如果这里能看到 sdb说明内核已经识别只是 lsblk 输出可能没刷新执行 udevadm settle 再看一次。如果是传统 SCSI 虚拟磁盘可以触发一次总线重新扫描for host in /sys/class/scsi_host/host*; do echo - - - $host/scan; done执行后立即 lsblk 检查。看 dmesg 日志dmesg | grep -i sd\|virtio\|sdb能看到磁盘设备相关日志比如 sdb 是否被发现、是否有 IO 错误。如果以上都不行在业务窗口允许的情况下重启一次。云平台控制台挂载的磁盘在大多数虚拟化环境里支持热插拔识别但极少数老型号虚拟化平台对热添加支持不彻底重启是最干脆的兜底方案。排查的时候不要急一块磁盘没有出现无非是链路问题、驱动问题、平台问题三类一层层确认就好。最忌讳的是 lsblk 没看到新盘就反复执行 pvcreate那样只会得到Device /dev/sdb not found的报错。5. 扩容实操中的翻车现场与保险措施5.1 最容易踩的雷设备名看错、类型选错、XFS 不可缩扩容本身不复杂但我接手过的扩容事故几乎都集中在三个点上。第一个是设备名看错。pvextend、pvcreate 都是不可逆或者很难逆转的操作如果你机器上有 /dev/sda系统盘和 /dev/sdb新数据盘手一抖把 pvcreate /dev/sda 敲下去系统盘直接变成 PV引导和数据都可能出问题。我的习惯是操作前先用 lsblk -o NAME,SIZE,MODEL,SERIAL 对一遍设备和盘的大小、型号确认哪个是目标盘。第二个是文件系统类型选错。XFS 的根分区用 resize2fs 是无效的会提示 superblock 不对ext4 的根分区用 xfs_growfs 也会直接报错。扩容前用一次 df -hT / 确认类型比事后排查省太多时间。第三个是把 XFS 当成 ext4 一样能缩能扩。XFS 文件系统只支持扩容不支持缩小。如果你哪天看到根分区太大想缩一缩这种需求正确的做法是备份、重建 LV、恢复数据而不是用 lvreduce 去缩。任何对 XFS 的 lvreduce 尝试都可能让文件系统元数据错乱这是我在实际工作中非常忌讳的操作。还有一个隐藏的坑lvextend -l 100%FREE 会把卷组里所有空闲空间都给当前 LV。如果你的 VG 里还有别的 LV 需要保留扩容余地这个命令就不合适建议用 -L 精确指定增长量。做之前用 vgs 看一眼 VFree明确这些空闲我要分多少出去。5.2 动手前的三道保险快照、fstab 备份、LV 路径核对我在生产环境做任何 LVM 操作之前都会花几分钟做三道保险这套流程帮我避免了至少三次事故保险一云平台快照。在控制台给系统盘打一份快照或镜像。快照是异步的确保快照状态变成已完成再继续否则快照可能不含最新数据。如果机器没有云平台快照能力可以用 LVM 本身的快照功能但对新手来说云平台快照更直观可靠。保险二备份关键配置和现有布局。执行cp /etc/fstab /etc/fstab.bak blkid /tmp/blkid_before_resize.txt vgs /tmp/vgs_before_resize.txt lvs /tmp/lvs_before_resize.txt这几行命令把你的文件系统表、设备 UUID、卷组和逻辑卷状态都留了个底。万一后续操作影响了启动还能参照这些文件恢复。保险三核对 LV 路径。在 lvextend 之前花五秒钟跑一遍 lvs 确认要扩容的 LV 路径准确。我见过有人把 /dev/cs/root 写成了 /dev/cs/boot扩容了不该扩的卷虽然不至于数据丢失但违背了操作意图。另外强烈建议把长命令放进 tmux 或 screen 会话里执行tmux new -s resize原因很现实扩容期间如果 SSH 断掉命令可能只执行一半虽然 LVM 有恢复机制但 tmux 能保证你的会话和命令在断连后继续跑完。这个习惯在抢修时尤其值钱。5.3 什么时候仍然需要重启什么时候完全不用写到这里把在线扩容和重启的边界说清楚省得大家误解。完全不用重启的操作已有 VG 空闲空间直接 lvextend -r 扩展根 LV全程不用重启。新磁盘热插拔成功、并入 VG 后再扩根 LV全程不用重启。云盘控制台扩容后内核已经识别到新容量且通过分区扩展 pvresize 完成空间认领全程不用重启。可能需要重启的情况云盘控制台扩容后lsblk 迟迟不显示新容量所有 SCSI 扫描手段都无效此时需要重启一次让内核重新读取磁盘容量。你操作的是非 LVM 分区比如 /boot 所在分区那不在本文讨论范围且通常需要更复杂的处理。误操作改了 /etc/fstab、/boot 下文件等启动相关内容这时机器会异常需要尽快修复并重启验证。一句话总结LVM 在线扩容的绝大多数场景都不需要重启而且这正是它作为生产环境根分区方案的核心价值。最后分享一点个人习惯扩容完成后我会顺手把根分区使用率降到安全范围以内但真正的收尾是排查空间为什么会被占满。常见做法是 du -sh /var/log /var/lib /home 等目录找出空间大户配置日志轮转、设置容器日志大小限制。毕竟扩容只是治标把容量规划和日志治理做好才是治本。这套组合下来CentOS Stream 9 的根分区基本上就很难再给你惹麻烦了。