openEuler根分区打满?LVM扩容报错排查与在线扩容实战指南
2026/9/17 3:45:18 网站建设 项目流程

1. 问题现场与核心逻辑

1.1 根分区打满后系统会发生什么

前阵子我碰上一台openEuler 20.03的服务器,现象非常典型:业务日志突然写不进去,数据库连接数飙升,SSH登录后敲命令都卡顿,df -h一看,根分区/的使用率妥妥停在100%。这种时候千万别慌,也别急着想着“删点东西算了”——先搞清楚一件事:根分区满了不是只影响你放文件,整个系统都会跟着遭殃

Linux的根分区是所有系统路径的挂载点,包括/var(日志、缓存)、/tmp(临时文件)、/usr(应用程序),甚至/run(运行时目录)。一旦/写满,最常见的就是服务起不来、日志丢失、临时文件无法创建,严重的直接导致某些进程崩溃或系统只读挂载。我见过最夸张的一次,一台测试机根分区100%后,连sudo命令都执行失败,因为sudo要写/var/log/sudo.log,盘满了根本写不进去。

这种场景下,很多人第一反应是“那我扩容呗”。理论上确实是这样,但真正操作起来,扩容报错的坑一个接一个——比如lvextend提示Insufficient free spacexfs_growfs提示设备忙,或者明明磁盘加了容量,系统却根本不认。这台openEuler 20.03就是这样,扩容命令敲下去直接报错,后面我会把整套排查思路和解决方案完整捋一遍,适合所有用LVM管理磁盘的Linux系统参考,不只是openEuler。

1.2 openEuler 20.03的磁盘管理方式:LVM原理

要搞清楚扩容为什么报错,得先明白openEuler 20.03默认的磁盘管理方式。openEuler 20.03是麒麟系(实际上源自CentOS/RHEL技术路线)的发行版,安装时默认使用**LVM(Logical Volume Manager)**来管理磁盘,这跟CentOS 8、RHEL 8的默认行为几乎一样。

LVM的逻辑很好理解,我用生活类比来说:把物理磁盘(比如一块500G的SATA盘)想象成一块大土地,LVM把它划分成若干个物理卷(PV,Physical Volume),相当于把土地切成几块“地块”。这些“地块”被合并进一个“土地储备中心”——也就是卷组(VG,Volume Group),然后你从储备中心里划出一块地来挂载使用,这就是逻辑卷(LV,Logical Volume)。

实际挂载到根分区的,就是这个LV。好处是扩容时不需要动物理分区表,只要卷组里有空闲空间,就能实时分配给LV,文件系统也能在线扩容。但问题也藏在这里:很多人扩容时根本不看VG里还有没有空间,直接对LV下手,不报错才怪。

所以当你执行扩容时报错,优先要确认三件事:

  1. 物理磁盘本身还有没有空余空间?——这决定你能不能扩PV。
  2. VG里有没有空闲空间?——这决定你能不能直接扩LV。
  3. 文件系统类型是什么?——xfs和ext4扩容的命令完全不同。

下面我用实际命令来拆解这整个过程,顺便把报错现场一个一个还原。

2. 排查思路:先搞清楚扩容报错的真正原因

2.1 第一步:确认分区使用率与挂载点

遇到根分区100%的问题,最先做的不是扩容,而是把现状摸清楚。我建议按这个顺序执行:

df -hT

这能看到每个挂载点的文件系统类型、容量、使用率。输出长这样:

Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/openeuler-root xfs 200G 200G 20K 100% /

注意第一列,如果根分区是/dev/mapper/xxx-root这种路径,那就确认走了LVM;如果直接是/dev/sda2这种,说明没有用LVM,扩容路径完全不同。在我这台openEuler 20.03上,根分区挂载的就是/dev/mapper/openeuler-root,文件系统是xfs,这很关键——xfs支持在线扩容,但不支持缩容,所以操作时不能缩回去,这一点后面会细说。

然后执行lsblk看整个磁盘拓扑:

lsblk

输出里能看到物理磁盘、分区、PV、LV的层级关系。比如:

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 500G 0 disk ├─sda1 8:1 0 1G 0 part /boot ├─sda2 8:2 0 199G 0 part │ └─openeuler-root 253:0 0 199G 0 lvm / └─sda3 8:3 0 300G 0 part

这个时候你已经能看到物理磁盘其实还有300G没有被LVM使用(sda3就是空闲空间)。如果lsblk里物理盘已经完全分配完了,那扩容思路就得换成“加新盘”或者“清理空间”,而不是干扩。

2.2 第二步:查看LVM卷组剩余空间

lsblk看完物理层,再看LVM层。执行:

pvdisplay vgdisplay lvdisplay

vgdisplay里有个关键字段:Free PE / Size。比如:

--- Volume group --- VG Name openeuler Format lvm2 Metadata Areas 1 Metadata Sequence No 1 VG Access read/write VG Status resizable VG Size <199.00 GiB PE Size 4.00 MiB Total PE 50943 Alloc PE / Size 50943 / <199.00 GiB Free PE / Size 0 / 0

看到Free PE / Size 0 / 0就明白了——卷组里已经一点空闲空间都没有了。这就是为什么执行lvextend -L +50G /dev/mapper/openeuler-root会报错,常见的报错信息有:

Insufficient free space: 12800 extents needed, but only 0 available

或者:

Cannot extend volume group "openeuler" with 1 physical volumes: not enough free space

到了这一步,问题根源已经清楚了:LV想扩容,但VG里没有空间可分配。没有空间,你怎么扩都报错。所以真正的解法是——先给VG扩展物理卷(PV),再给LV扩容,最后扩展文件系统。

2.3 第三步:区分物理盘容量与LVM分配

这一步最容易混淆。很多人看到lsblksda总共有500G,但LVM只用到了199G,就以为自己可以直接扩。这里有个关键区别:物理盘容量 ≠ LVM可见容量。因为LVM只把加入了PV的分区纳入管理,磁盘上未分区的空间、未加入PV的分区,对VG来说都是“不可见的”。

所以你在虚拟机、云平台控制台把磁盘从500G扩到800G之后,进系统执行df -h,使用率还是100%,因为新增的300G根本没有创建分区、没有加入PV,LVM感知不到。很多人的扩容报错,本质上是卡在这一步——只加了物理盘,没让系统“认”这个新空间。

正确操作是:把磁盘新增的空间创建成新分区,然后pvcreate把这个分区加为物理卷,再vgextend扩展卷组,之后才能lvextend去扩容逻辑卷。

还有一种情况——lsblk里已经有一个未使用的分区(比如sda3占了300G),但你pvdisplay里看不到它。那就说明这个分区还没有被初始化为PV,需要先用pvcreate /dev/sda3把它加进来。

3. 实操:三种扩容路径与报错应对

3.1 路径一:卷组有剩余空间时的在线扩容

如果你检查了vgdisplay,发现Free PE / Size不为0,恭喜你,这是最简单的情况。直接在线扩LV就行。

先看逻辑卷路径和文件系统类型(前面已经在df -hT确认过了),然后执行扩容:

lvextend -L +50G /dev/mapper/openeuler-root

这里-L +50G意味着在现有基础上增加50G,如果写-L 250G则是把LV直接扩到250G(注意不是增加,是最终大小)。个人建议用+号写法,免得你记错当前大小导致扩过头或者扩少了。

命令成功会输出类似:

Size of logical volume openeuler/root changed from 199.00 GiB (50943 extents) to 249.00 GiB (63743 extents). Logical volume openeuler/root successfully resized.

到这里很多新手就以为完事了,实际上还差最关键的一步:扩展文件系统。因为LV扩容后,文件系统不知道底层变大了,不扩展的话df -h还是显示原来的大小。

xfs用:

xfs_growfs /

ext4用:

resize2fs /dev/mapper/openeuler-root

执行完df -h确认,根分区应该已经变大了。

注意:xfs文件系统扩容是不支持缩容的,所以扩容前务必确认你要扩的空间够用,别想着“先扩了再缩回来”。ext4倒是可以缩容,但那需要离线操作,生产环境很不建议。

3.2 路径二:物理磁盘有剩余空间时扩展PV

这是本次openEuler 20.03报错场景里最常见的路子——磁盘在云控制台或者虚拟机软件里已经加了容量,但系统里根本看不到。处理步骤依次是:

第1步:新空间创建分区

查看当前磁盘分区表:

fdisk -l /dev/sda

假设你原来只有sda1和sda2两个分区,磁盘从500G扩到800G后,剩余300G是未分区状态。执行:

fdisk /dev/sda

依次输入:

  • n(新建分区)
  • p(主分区)
  • 分区号选默认(回车即可,通常下一个可用的就是3)
  • First sector 默认(直接回车)
  • Last sector 默认(直接回车,使用全部剩余空间)
  • t(修改分区类型)
  • 8e(Linux LVM)
  • w(保存退出)

这一步如果报错Partition 3 already exists,说明系统里其实已经有分区了,但可能没被LVM认。那就跳过fdisk,直接看第2步。

第2步:初始化物理卷

pvcreate /dev/sda3

正常输出:

Physical volume "/dev/sda3" successfully created.

如果提示Device /dev/sda3 not found,需要先执行partprobe让内核重新读取分区表,或者干脆重启(生产环境不推荐重启的话,用partprobe就能解决)。

第3步:扩展卷组

vgextend openeuler /dev/sda3

注意这里openeuler是我的VG名字,你在自己机器上执行时先vgdisplay看清楚VG Name再替换。

输出正常是:

Volume group "openeuler" successfully extended

这时再执行vgdisplay,就能看到Free PE / Size不再是0了。这个说法有点绕,直接用vgdisplay看更直观。

第4步:扩展LV与文件系统

lvextend -L +300G /dev/mapper/openeuler-root xfs_growfs /

搞定。df -h确认下根分区是否已经更新。

3.3 路径三:没有额外磁盘空间时的应急处理

如果机器本身没有额外空间了,磁盘就那么大,也没有云控制台加盘的条件,那扩容这条路暂时走不通。这时候先做应急,把系统盘的使用率压下来,保住业务,再去申请资源扩盘。

梳理一下我常用的清理方法:

日志压缩与清理

journald日志是最容易吃满空间的东西之一,尤其是/var/log/journal目录。执行:

journalctl --vacuum-size=500M

这会把历史日志裁到500M以内,效果立竿见影。想永久限制journal日志大小,改配置:

mkdir -p /etc/systemd/journald.conf.d cat > /etc/systemd/journald.conf.d/size.conf <<'EOF' [Journal] SystemMaxUse=500M EOF systemctl restart systemd-journald

包管理器缓存清理

openEuler 20.03的yum/dnf缓存通常也在/var/cache/dnf,执行:

yum clean all

能释放不少空间,具体取决于你用yum装了多少东西。

大文件排查

如果清理完日志和缓存还是不够,就得找一找哪些文件在“偷偷”吃空间:

du -x --max-depth=1 / | sort -rh | head -20

这一条命令从根开始逐层找最大的目录,然后逐层深入,直到定位到具体的大文件。常见的“吃空间大户”有:后端服务的日志文件(比如/var/log/nginx/access.log)、Docker的overlay2目录(/var/lib/docker)、数据库的binlog(/var/lib/mysql)等。

临时文件与core dump

rm -rf /tmp/* rm -f /var/crash/*

这些目录往往堆着一堆没用的临时文件和崩溃转储,清理完系统会松快很多。

这几种方式都是应急手段,能把使用率先压到70-80%,保证系统能正常写日志、跑服务。但治标不治本,后续还是要申请新磁盘空间,按前面路径二的流程做一次真正的扩容。

4. 常见报错速查与避坑经验

4.1 典型报错对照表

这个场景下我收集了比较常见的报错以及对应的解决办法,整理成一张表,方便直接对照排查。

报错信息原因解决方案
Insufficient free space: NNNN extents needed, but only 0 availableVG里没有空闲空间新磁盘分区 -> pvcreate -> vgextend,然后再lvextend
Cannot extend volume group ... no free space同上,VG可分配的物理空间不足同上,重点检查物理盘有没有新加容量
xfs_growfs: / is not a mount point命令参数写错直接执行xfs_growfs /,不需要指定设备路径
resize2fs: Bad magic number in super-block在xfs文件系统上用了resize2fs改为xfs_growfs /,xfs用xfs_growfs,ext4用resize2fs
Partition 3 already exists磁盘上已有分区但未加入PV跳过fdisk,直接pvcreate对应分区
Physical volume /dev/sda3 not found内核还未识别新分区执行partprobe重新读取分区表,或重启
multipathd: sda: failed to get ...多路径环境磁盘盘符未刷新云环境下确认块设备状态,重新扫描scsi总线
No space left on device,但df -h显示不到100%inode耗尽df -i检查inode使用率,确认是否有大量小文件占满inode

最后一条值得单独强调。inode耗尽是个“隐形杀手”,它不会显示成磁盘满了,但症状一模一样——文件写不进去、服务报错。我遇到过/var/spool下大量邮件小文件把inode吃满的情况。排查命令是df -i,如果IUse%接近100%,解决办法是删除无用的小文件,把文件数量压下来。

4.2 我的几条实操心得

做了这么多年的系统运维,扩容这件事踩过的坑比吃的饭还多。分享几条自己的心得,希望你能少走弯路。

第一条:扩容前先用df -i看一眼inode。别光盯着存储空间看。如果inode爆了,就算你扩了磁盘,写入照样失败。用df -i看一下每块分区的inode使用率,特别是/var/home这种可能堆大量小文件的分区。

第二条:不要在磁盘使用率100%的时候做lvextend。听起来有点反直觉——我扩容不就是为了解决100%吗?我的意思是,如果你还没获得新磁盘空间,只是拿“清理空间”当挡箭牌,那你更应该先扩充物理存储,再决定是清理还是扩容。如果在根分区已经100%的状态下执行某些进程会持续写盘的扩容操作,有中断风险。稳妥的操作是:先清理出一部分空间让系统喘口气,再扩容。

第三条:xfs_growfs不需要指定设备路径,直接对挂载点操作就行。很多新手习惯看教程里的完整写法,比如xfs_growfs /dev/mapper/openeuler-root,这个写法其实也能用,但在openEuler 20.03上,直接xfs_growfs /更稳。原因是xfs_growfs命令针对的是挂载点,不是设备文件,传挂载点才是最标准的方式。

第四条:云环境下扩容后别忘了扫描磁盘。如果你用的是云服务器,在控制台加完磁盘容量后,系统内不一定能自动识别。这种情况执行:

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

或者重启。我最初就是忘了这一步,导致磁盘容量加了好几次都没生效,白白折腾了半天。

第五条:生产环境扩容前先备份。虽然LVM在线扩容是成熟技术,但谁也不能保证万无一失。有备份的话,即使扩出问题也能回滚,这个钱和功夫省不了。

4.3 一次真实的扩容复盘

最后把这次openEuler 20.03的排查过程完整复盘一遍,更直观地展示实际处理的节奏。

现象:df -h显示根分区/使用率100%,系统卡顿,日志写入失败。 排查:lsblk看到sda磁盘总大小500G,sda2分区199G被LVM使用,sda3分区300G未被使用。 关键点:pvdisplay里没有sda3这个PV,vgdisplay里Free PE / Size为0。 报错:执行lvextend -L +300G /dev/mapper/openeuler-root,提示Insufficient free space。 定位:300G的空间确实存在,但没有初始化为物理卷,LVM完全看不到它。 解决:

  1. pvcreate /dev/sda3——把sda3加入LVM物理卷。
  2. vgextend openeuler /dev/sda3——把新的PV扩展到VG中。
  3. lvextend -L +300G /dev/mapper/openeuler-root——扩展LV。
  4. xfs_growfs /——在线扩展xfs文件系统。 验证:df -hT确认根分区从199G扩到了499G,使用率降到50%左右。

整个过程其实不超过10分钟,但之前卡在报错上花了大半天。所以我想强调的是:扩容报错时,第一反应应该是“VG里有没有空间”,而不是“为什么lvextend不给过”。搞清楚了LVM的工作机制,90%的扩容问题都不是问题。

根据我个人在openEuler 20.03上的使用体验,它的LVM链路和CentOS/RHEL非常接近,所以这套操作思路放到同类系统上基本通用。如果你用的不是LVM而是裸分区(比如直接挂载的/dev/sda2),那扩容路径完全不同,需要借助分区工具或直接重建文件系统,但那就是另一篇文章的内容了。

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

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

立即咨询