知道你的 Linux 根分区或者 /home、/data 这些业务分区空间不够了,正翻各种资料想扩大文件系统。老实说,extend filesystem on Linux 这件事,尤其是带 root 分区参与的时候,确实不能莽,我见过太多人一上来就用 fdisk 删了分区重建,结果分区表损坏、文件系统起不来,最后只能翻备份。这篇文章就围绕“在 Linux 上扩展文件系统(root 和其他分区)”这个主题,把我这些年踩过的坑和验证过的完整流程整理出来。不管你用的是 CentOS、Ubuntu 还是国产发行版,只要底层存储思路清楚,照着做基本都能搞定。
做扩容之前,需要先弄明白三件事:当前系统是 LVM 还是普通分区布局,文件系统类型是 ext4 还是 xfs,以及新增空间是从哪来的。这三个问题的答案直接决定了后续该敲哪条命令。文章前半部分会教你怎么快速摸清现状,后半部分是实操步骤、常见报错和处理经验,适合刚接触 Linux 系统维护的新手,也适合平时主要写业务代码、偶尔被拉去救火的开发同学收藏备查。
1. 动手之前,先搞清楚你的存储架构
1.1 扩展文件系统不等于直接改分区
很多朋友一看到磁盘满了,第一个反应就是拿 fdisk 删掉分区重建,或者网上搜个教程直接 resize2fs。我在实际排障中见过太多次这种“大力出奇迹”的操作,结果无非两种:分区表被搞坏,或者文件系统元数据损坏。为什么?因为 Linux 下的文件系统扩容不是“磁盘变大了系统就自动变大”,它是一条完整的链路:物理磁盘到分区,分区到物理卷和逻辑卷(如果走 LVM),逻辑卷再到文件系统。这四个层面只要有一层没同步,你的容量就加不上去。
所以我通常会给来求助的人先泼盆冷水:在敲任何命令之前,先把下面三个问题搞清楚。
第一个问题,文件系统类型是什么。ext4 用 resize2fs,xfs 用 xfs_growfs,btrfs 又有自己的一套,工具用错了,命令一跑就直接报 Bad magic number。第二个问题,有没有用 LVM。如果启用了 LVM,你是没有办法直接对某个分区做 resize 的,得走 pvresize 给物理卷扩容,再 lvextend 给逻辑卷扩容,最后调整文件系统。如果没有 LVM,那就是分区表维度的扩容,要用 growpart 或 parted 去调整分区边界。第三个问题,新增的空间是怎么来的。云盘在控制台扩容后,系统里往往不能立刻识别到新空间,需要重新扫描 SCSI 设备;虚拟机的虚拟磁盘变大后,也需要在客户机里做一遍磁盘扫描才能看到真实容量。只有先搞清楚这些,后面每一步才有的放矢。
1.2 用哪几条命令快速摸清现状
判断存储布局最快的方式就是组合使用下面这几条命令,我每次排障基本就靠它们:
bash复制lsblk
df -hT
pvs && vgs && lvs
blkid
findmnt /
- lsblk 看块设备树整体结构,能明确看到磁盘、分区、LVM 之间的层级关系,还能看到挂载点。
- df -hT 看文件系统占用和类型,确认哪个分区快满了。
- pvs/vgs/lvs 查看 LVM 的物理卷、卷组、逻辑卷大小,以及卷组里还有没有空闲空间。
- blkid 查看文件系统类型和 UUID。
- findmnt / 确认根文件系统的挂载信息。
举个例子,一台典型的云主机输出是这样的:
bash复制$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 100G 0 disk
├─vda1 252:1 0 1G 0 part /boot
└─vda2 252:2 0 99G 0 part
└─centos-root 253:0 0 50G 0 lvm /
从这个输出能读出很多信息:磁盘 vda 总大小 100G,vda1 是 /boot,vda2 是 LVM 的物理卷,里面建了一个 50G 的逻辑卷挂载在根目录。如果根空间不够,并且磁盘 vda 已经变成了 120G,那就说明云平台层面的容量已经扩好了,剩下的工作是让系统识别新空间、扩展物理卷和逻辑卷、调整文件系统大小。这个完整链路就是 LVM 场景扩容的典型路径。
下面再给一个命令对照表,方便你按图索骥:
| 命令 | 用途 | 需要关注的关键字段 |
|---|---|---|
| lsblk | 看磁盘/分区/LVM 层级关系 | SIZE、TYPE、MOUNTPOINT |
| df -hT | 看文件系统占用和类型 | Use%、Type |
| pvs | 看物理卷大小 | PV Size、Free |
| vgs | 看卷组空间分布 | VSize、VFree |
| lvs | 看逻辑卷大小 | LSize |
| blkid | 看 UUID 和文件系统类型 | TYPE |
| findmnt / | 确认根挂载路径 | SOURCE、FSTYPE |
这组命令不是背下来就完事,关键是培养一个习惯:每次扩容前都跑一遍,确认当前状态和你预想的一致,再动手。很多时候报错就是因为实际架构和命令行预期不一致。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 扩展前的准备工作与风险控制
2.1 数据安全永远排在第一位
扩展文件系统虽然支持在线操作,但毕竟涉及磁盘分区和文件系统元数据,谁也不敢保证过程中不会断电、误操作、系统崩溃。生产环境我的习惯是:先做快照或备份,再考虑其他步骤。虚拟机直接打快照,云主机开自动快照或者做一个自定义镜像,物理机则至少保证有可用的全量备份。如果实在没有备份条件,至少要确保能通过带外管理或远程控制台登录,不然扩容过程中网络断了,系统又起不来,你连上去抢救的机会都没有。
这里有个容易忽略的细节:快照一定要在扩容操作之前打,而不是扩容到一半再打。因为中途状态的快照可能包含不完整的 LVM 元数据,回滚的时候反而把你坑了。另外,如果是云平台上的系统盘,快照尽量选择磁盘级别的整盘快照,别只对某个分区做,这样回滚时才能完整恢复到扩容前状态。
2.2 确认文件系统类型和挂载状态
用 blkid 或者 df -hT 确认根分区和业务分区的文件系统类型,这一步直接决定你后面用哪个 resize 工具。常见组合如下:
- ext4 文件系统:使用 resize2fs,支持在线扩大。
- xfs 文件系统:使用 xfs_growfs,支持在线扩大,但注意 xfs 只能扩大不能缩小。
- btrfs 文件系统:使用 btrfs filesystem resize 命令。
如果分区正在被大量写入,建议先评估业务影响,必要的话安排一个维护窗口,尤其是数据库、消息队列这类对 IO 敏感的应用。在线扩容时最怕的是文件系统在写入高峰期被 resize 操作和业务写入同时挤压,虽然不会直接导致数据丢失,但 IO 等待延长、响应变慢是常有的事。另外一个细节是,resize 之前执行一下 sync,确保缓存中的数据落盘,再开始操作。
2.3 切换 root 与确认系统权限
扩展文件系统必须有 root 权限,普通用户通过 sudo 也只能执行部分命令。登录服务器后建议先切到 root 环境,Ubuntu 可以用 sudo -i,CentOS/RHEL 可以用 su -。有些系统默认锁定了 root 账号,比如部分国产发行版,会出现提示 root is locked 的情况,这种场景下需要先通过 sudo 解锁 root:sudo usermod -U root,或者用 passwd root 设置一个新的 root 密码。如果你不是在一台已经登录的机器上操作,而是连系统都进不去,那就要走单用户模式或者救援模式了,这个后面在常见问题部分再细说。
还有一个容易被忽略的点:检查系统里有没有必要的服务依赖挂载点路径。比如 Docker 的数据目录如果挂在 /var/lib/docker,而 / 分区扩容后设备路径发生变化,容器就有可能会起不来。LVM 的设备路径一般比较稳定,但普通分区扩容后,如果 /etc/fstab 里写的是设备名而不是 UUID,同样会出现挂载异常。所以我建议 fstab 一律用 UUID,不要用 /dev/sda1 这种设备名。
3. LVM场景:扩展根文件系统的完整步骤
3.1 让系统识别到新增的磁盘空间
LVM 场景下,扩展 root 文件系统的前提是物理磁盘已经变大。如果你用的是云主机,通常需要在控制台先扩容云盘;如果是 KVM 虚拟机,则需要先在宿主机上把虚拟磁盘调大。这一步做完后,虚拟机内部直接 lsblk 往往看不到新容量,需要重新扫描磁盘总线。
对传统 SCSI 设备,典型的重扫命令是:
bash复制for host in /sys/class/scsi_host/host*/scan; do echo "- - -" > $host/scan; done
对 virtio-blk 类型的云盘(设备名通常是 vda),可以尝试:
bash复制echo 1 > /sys/block/vda/device/rescan
或者直接重启实例。重启虽然简单粗暴,但在生产环境成本较高,所以能在线 rescan 就尽量在线。执行完重新 lsblk,你会看到磁盘总容量已经变大,但分区大小还维持原样。别急,这正是我们接下来要处理的。
3.2 扩展物理卷和逻辑卷
假定你的 LVM 物理卷是 /dev/vda2,根逻辑卷路径是 /dev/mapper/centos-root。第一步扩展物理卷:
bash复制pvresize /dev/vda2
执行后可以用 pvs 或者 vgdisplay 查看卷组的可用空间变化。如果 vda2 对应的 PV 已经识别到新容量,你会看到 VFree 这个字段变大,这就是可以分配给逻辑卷的剩余空间。
接下来扩展逻辑卷:
bash复制lvextend -l +100%FREE /dev/mapper/centos-root
这里我把整个卷组的空闲空间都给了根逻辑卷,适合确认根分区是唯一需要扩容目标的情况。如果你还需要给其他逻辑卷留空间,那就用更精确的方式:
bash复制lvextend -L +20G /dev/mapper/centos-root
意思是只给根逻辑卷增加 20G。实际操作中我建议先用 vgs 看下 VFree 总量,再决定分配策略,别一次性把空间全给某个 LV。毕竟后面哪块业务又要扩,你说不定就得马上腾挪,预先留一点空间更稳妥。
3.3 调整文件系统大小
逻辑卷变大了,文件系统并不会自动跟着变大,还需要手动 resize。
如果你的根文件系统是 ext4:
bash复制resize2fs /dev/mapper/centos-root
这条命令执行后,resize2fs 会读取逻辑卷当前大小,然后把文件系统扩展到对应尺寸。一般几秒钟就完成了,输出类似:
bash复制resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/mapper/centos-root is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/mapper/centos-root is now 52428800 (4k) blocks long.
如果你的根文件系统是 xfs:
bash复制xfs_growfs /
注意,xfs_growfs 后面跟的是挂载点,不是设备路径。这一点和 resize2fs 完全不一样,用错会出现无法识别文件系统的报错。xfs_growfs 执行时会自动检查当前容量和目标容量,然后在线增长。
3.4 验证扩容结果
最后一步是验证,不要偷懒,直接看结果:
bash复制df -hT /
lsblk
lvs
df 显示的是文件系统可用容量,lsblk 和 lvs 显示的是分区和逻辑卷大小。正常情况这三者的数值应当匹配。如果 df 没变,先别慌,回头检查是不是没执行 resize2fs 或 xfs_growfs;再检查 lvextend 是不是真的给了正确的逻辑卷。很多时候你扩的是 vg_var,却期待 / 变大,那就当然没变化。
我在生产环境见过一个比较隐蔽的问题:lvextend 扩展后,resize2fs 报了 Resizing 成功,但 df 还是原来的值。后来发现是文件系统当时存在多个挂载点,我们改的是其中一个,而实际访问的是另一个挂载路径。所以验证的时候建议确认一下 findmnt / 的输出,确保挂载路径和 lvextend 的目标一致。
4. 非LVM场景:扩展普通分区
4.1 扩展根分区(非LVM)
没有 LVM 的环境里,根分区默认是直接建在物理分区上的,比如 /dev/vda1 挂载在 /。这种情况下想扩展,需要先调整分区表,再调整文件系统。如果你还想保留分区里的数据,唯一安全的方式是保持分区起始扇区不变,只把结束位置往后移动。
推荐用 growpart,这个工具在 cloud-utils-growpart 包里。CentOS/Red Hat 系安装命令:
bash复制yum install cloud-utils-growpart
然后扩展第一个分区:
bash复制growpart /dev/vda 1
growpart 会读取当前分区表的起始扇区,然后把分区扩展到磁盘末尾,整个过程不删除分区,相对安全。操作完成后执行 partprobe:
bash复制partprobe /dev/vda
再根据文件系统类型调整。ext4 用 resize2fs:
bash复制resize2fs /dev/vda1
xfs 用 xfs_growfs:
bash复制xfs_growfs /
如果你用的是 parted 的 resizepart,命令是:
bash复制parted /dev/vda resizepart 1 100%
注意,parted 的 resizepart 对在线状态支持一般,如果是根分区且系统无法卸载它,有些环境下会提示分区正忙,此时要么安排维护窗口重启,要么老老实实用 growpart。还有一个点:如果是 MBR 分区表,单个分区最大只能到 2T,超过 2T 建议转 GPT,但非空盘转换 GPT 有风险,需要额外评估。
4.2 扩展业务分区(/home、/data)
业务分区的扩展思路和根分区类似,但也有更灵活的方案,尤其是当 /home 或 /data 是独立磁盘时,你不一定非要原地扩大,可以加一块新盘挂载到更深层的目录,或者用 LVM 把多块盘聚合。举个实际例子,我之前帮一个测试环境扩 /home,源磁盘上已经没有多余空间了,直接在虚拟机里加了一块 100G 的虚拟磁盘,然后进行如下操作:
bash复制fdisk /dev/sdb
# n 创建新分区,p 主分区,w 写入分区表
mkfs.ext4 /dev/sdb1
mkdir -p /home/data
mount /dev/sdb1 /home/data
然后把挂载信息写入 /etc/fstab,注意用 UUID 而不是设备名:
bash复制blkid /dev/sdb1
echo 'UUID=xxxx /home/data ext4 defaults 0 2' >> /etc/fstab
这种做法的优点是隔离性强,即使 /home 根分区后面又满了,数据在独立盘上不受影响。缺点是想把新空间直接并入原来的 /home 挂载点会麻烦一点,需要做数据迁移和绑定挂载,不如一开始就规划 LVM。
4.3 针对 XFS 文件系统的处理
非 LVM 环境下遇到 xfs 文件系统,需要额外记住 xfs 的几个特性。第一,它只能用 xfs_growfs 扩大,不能缩小,所以空间规划要留足余量。第二,xfs_growfs 挂载点参数是关键,对根文件系统就是 xfs_growfs /,对 /data 就是 xfs_growfs /data。第三,如果磁盘上还有其他分区占据着后续空间,比如 vda1 后面还有 vda2,那你不能直接把 vda1 扩到磁盘末尾,必须先确认相邻空间可用。实际操作中,我见过有人拿 resize2fs 处理 xfs,结果命令直接报错:Bad magic number in super-block,这就是没用对工具。
xfs 分区扩容后还有个验证技巧:xfs_info / 可以查看文件系统的 block 等信息,虽然 df 更直观,但排查问题时 xfs_info 能看到更多底层细节。
5. 特殊场景:虚拟化环境、云主机与 WSL
5.1 KVM/VMware 虚拟机磁盘扩容
KVM 和 VMware 虚拟机扩容,都要先在宿主机层面把虚拟磁盘调大。KVM 常用 qemu-img:
bash复制qemu-img resize /var/lib/libvirt/images/vm.qcow2 200G
如果有图形化管理界面,也可以用 virsh vol-resize:
bash复制virsh vol-resize --pool default --vol vm.qcow2 --capacity 200G
VMware 平台则是在 vSphere 或 Workstation 的虚拟机设置里直接修改磁盘大小。宿主机扩容完成后,虚拟机内部不要急着直接 fdisk,先 rescan 磁盘总线,让操作系统识别到新增空间。这里要特别强调一点:qemu-img resize 对 qcow2 格式是安全的,但前提是做好快照或者备份,因为云盘文件一旦变大,往回缩是很难的,缩了也可能损坏数据。
5.2 云主机系统盘扩容
云主机扩容系统盘,通常路径是:控制台扩容云盘,回到实例内扩容分区,再调整文件系统。以阿里云、腾讯云这类主流云平台为例,控制台操作完成后,实例内一般会出现一个比原来更大的磁盘容量,但分区大小不变。这时候需要用到 growpart 或者平台自带的扩容工具。很多云厂商也提供了控制台的一键扩容,但底层逻辑其实就是 growpart + resize2fs/xfs_growfs。
有个细节值得注意:如果是根分区所在云盘,而且用的是 MBR 分区表,容量上限是 2T,超过 2T 就只能用 GPT 或者把数据迁移到更大的新盘。还有,部分云平台扩容后必须重启实例才能识别到新空间,重启前记得关闭可能影响一致性的服务,并把持久化数据落盘。
5.3 WSL 子系统的文件系统扩容
本地开发用的 WSL 也会遇到根分区空间不够的问题,很多人不知道这个怎么扩。WSL 的文件系统其实放在一个 ext4.vhdx 虚拟磁盘里,不能直接在 Linux 内扩展,需要在 Windows 侧处理。
先把 WSL 停掉:
bash复制wsl --shutdown
然后打开 diskpart,找到发行版对应的 vhdx 文件:
code复制diskpart
select vdisk file="C:\Users\你的用户名\AppData\Local\Packages\...\ext4.vhdx"
expand vdisk maximum=51200
exit
回到 WSL 里,查看当前块设备:
bash复制lsblk
如果是单分区且没有复杂结构,直接对根文件系统做扩展。假设块设备是 /dev/sdb:
bash复制sudo resize2fs /dev/sdb
WSL 里一般不需要操作分区表,因为 vhdx 里通常就是一个完整的根文件系统镜像。如果你是在 WSL 上跑数据库或大数据任务,建议把虚拟磁盘大小一次性分足,因为 vhdx 是动态增长的,之后反复扩容很麻烦。另外,WSL 本身提示 “wsl needs updating” 这类版本问题时,优先升级 WSL,再处理磁盘。
6. 常见问题与排查技巧实录
6.1 resize2fs 报错:Bad magic number in super-block
这个报错我印象太深了,因为几乎每个月都能在社区看到类似提问。命令如下:
bash复制$ resize2fs /dev/vda1
resize2fs 1.46.5 (30-Dec-2021)
resize2fs: Bad magic number in super-block while trying to open /dev/vda1
原因基本就两个:一是文件系统不是 ext4,二是你指定的设备不对。遇到这种报错,先执行 blkid 看看分区类型。如果是 xfs,就改用:
bash复制xfs_growfs /
如果是其他设备被占用,确认设备路径没错再试。还有一个冷门情况:分区上根本没有文件系统,比如是 LVM 的 PV 区域,resize2fs 当然不认识,需要先用 pvresize 处理。
6.2 df -hT 显示的容量没变
扩容命令都执行成功了,df 却还是老样子,排查顺序很重要。第一步看 lsblk,确认磁盘、分区、逻辑卷大小是不是真的变了。如果磁盘没变,说明底层空间没被系统识别,需要 rescan 或重启。第二步看 vgs 和 lvs,确认有没有把空间给到正确的 VG/LV。很多人扩了 A 卷,却指望 B 分区变大,那肯定不可能。第三步看文件系统,确认有没有执行 resize2fs 或 xfs_growfs。我见过一个同事扩容逻辑卷后忘记 resize2fs,直到业务报磁盘满才发现。
6.3 分区表刷新失败或设备忙
用 growpart 或 parted 扩展分区后,有时内核不会自动读取新分区表,这时需要:
bash复制partprobe /dev/vda
如果提示设备忙,可以尝试:
bash复制partx -u /dev/vda
对于根分区这种无法卸载的分区,在线刷新分区表偶尔会失败,最稳妥的办法是维护窗口期重启,让内核重新读取分区表。事前如果你能确认新分区已经写入磁盘,重启后直接执行文件系统扩展即可。
6.4 扩充后服务或挂载异常
这个问题常被忽略。扩容后系统重启,LVM 设备路径一般会自动识别,但普通分区的设备名可能会变,比如从 /dev/sda1 变成 /dev/sdb1,结果 /etc/fstab 里写的还是旧的设备名,系统就挂载不上。我的习惯是 fstab 里全部用 UUID,不要用设备名。另外,如果 Docker 的存储目录正好在扩容的分区上,扩容后容器可能因为挂载传播问题无法启动,建议在维护窗口先停容器,再扩容,最后启动容器。
6.5 常见问题速查表
| 现象 | 排查方向 | 处理办法 |
|---|---|---|
| resize2fs 报 Bad magic number | 文件系统类型或设备路径不对 | blkid 确认类型,xfs 换 xfs_growfs |
| df 容量没变 | 未执行文件系统 resize、空间给错 LV、底层未识别 | lsblk/vgs/lvs 逐步确认后补齐步骤 |
| 分区表刷新失败 | 分区被占用或内核未读取新表 | partprobe、partx -u,或重启 |
| 扩容后服务异常 | 设备路径变化或挂载点丢失 | fstab 使用 UUID,确认挂载后再拉起服务 |
| root 被锁定或无法登录 | root 密码/锁定状态问题 | 单用户/救援模式解锁 root,重置密码 |
| xfs 使用 resize2fs 报错 | 工具用错 | 改用 xfs_growfs,注意挂载点参数 |
6.6 root 无法登录或 root 被锁定的处理思路
热词里出现很多 root 相关的问题,其实和扩容也有关系。比如你正准备进系统扩容,结果 root 进不去,提示 root is locked。这种情况多半是系统策略锁定了 root 账号,或者你忘记密码了。处理方式一般是通过单用户模式或者 live 环境进入系统,然后执行 usermod -U root 解锁,或者 passwd root 重置密码。还有一个更常见的场景:根分区已经满了,系统反复重启起不来,这时候需要进入救援模式,先清理一些空间出来,再继续扩容操作。说句实话,如果根分区满到系统起不来,在线扩容的优先级反而没有“想办法删点日志腾出空间”高,所以日常监控 df 使用率非常重要,别等到 100% 再处理。
7. 最后分享几点实操体会
前面讲了很多技术步骤,这里聊点我自己的习惯。每次扩容前,哪怕我对环境再熟悉,也会先跑一遍 blkid、lsblk、vgs、df -hT,确认文件系统类型和分区结构。这一步不花多少时间,但能避免大量低级错误。我亲眼见过同事在 xfs 分区上跑 resize2fs,把文件系统弄到需要 fsck 去修复,虽然最后数据没丢,但那几个小时的压力太大了。
另外,生产环境扩容前一定要做快照,这句话我说再多也不嫌多。云主机有快照功能就开快照,虚拟机就做虚拟机快照,物理机就至少准备整盘镜像。没有快照的扩容操作,本质上是拿生产数据赌运气。在线扩容 root 分区时,操作前先 sync,操作后再看一遍 df 确认挂载点容量,别急着让业务恢复。
还有一个小技巧:LVM 环境下,扩容前先看 vgs 的 VFree 大小。如果 VFree 还有充足空间,你只需要 lvextend + resize2fs/xfs_growfs 几步就搞定了;如果 VFree 是 0,你才需要去扩物理卷或加新盘。很多人一上来就 pvresize,结果发现 PV 本来就没有新空间,那只是浪费时间。最后,如果你的需求不止一次,现在开始规划分区时就把空间一次性给够,或者直接全面启用 LVM 和 xfs,对后续运维会省心很多。
