服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-10-08 简米科技 3,592 字 8 分钟阅读

CentOS虚拟机清理后空间未释放怎么办?虚拟机磁盘空间不回收

导读明明删了 CentOS 虚拟机里的日志、缓存,df -h 一看空间还是没变,心里直接冒出问号,CentOS虚拟机清理后空间不释放,核心原因是文件系统把磁盘块标记为“可写入”,但底层存储层——无论是 LVM 逻辑卷、分区还是宿主机上的 qcow2 镜像——依然把那些数据块当作已占用,所以空间“消失”得很冤, 接下……

明明删了 CentOS 虚拟机里的日志、缓存,df -h 一看空间还是没变,心里直接冒出问号。CentOS虚拟机清理后空间不释放,核心原因是文件系统把磁盘块标记为“可写入”,但底层存储层无论是 LVM 逻辑卷、分区还是宿主机上的 qcow2 镜像依然把那些数据块当作已占用,所以空间“消失”得很冤。 接下来聊一聊真实排查路径。

为什么 CentOS 虚拟机删了文件,可用空间却没增加?

先别急着重启虚拟机,多数情况下,文件确实删了,但空间被“扣”在另一个层面,2010 年后主流 LVM 和稀疏镜像机制都有这个“迟钝”特性。

文件被进程“咬住”不放手

这是最常见的原因,你在 CentOS 里删除一个正在被写入的日志文件,/var/log/messages,文件系统里没它了,但运行中的 rsyslogd 或系统服务还握着旧文件句柄,Linux 会把该文件占用的空间保留到最后一个进程关闭文件描述符为止,这种现象在日志系统里尤其频繁,一个长时间不重启的 CentOS 虚拟机经常因此丢掉几个 GB。

  • 使用 lsof +L1 找到已删除但仍被占用的文件。
  • 确认对应 PID 后,重启该服务或杀掉进程,空间才会真正交还给文件系统。

LVM 逻辑卷“只缩不缩”

如果你用 LVM 装 CentOS,情况更要小心。df -h 看到的是逻辑卷内部的可用空间,vgs 看到的是物理卷和卷组的空间,你在逻辑卷文件系统里删文件,只是腾出文件系统里的空闲块,LVM 本身不会自动收缩逻辑卷,除非跑 lvreduce,否则卷组的剩余空间永远不变,行业共识是:Linux 的删除操作只影响文件系统元数据,不影响块设备层的容量分配。

分区表没重新读取

如果你在虚拟机里扩展了虚拟磁盘,但分区依然按旧大小识别,清理后空间看起来像被“吃”了,这在扩容后特别常见,df 不会自动认识新块设备,除非跑 partprobe 或 resize2fs。

CentOS 虚拟机清理后空间不释放的排查步骤

CentOS虚拟机清理后空间未释放怎么办?虚拟机磁盘空间不回收

与其瞎猜,不如按顺序查,每一步都能定位到具体领域。

第一步:区分文件系统空间与设备空间

先跑三条命令,把视角拉开:

  • df -h /:看文件系统里的可用空间。
  • lvs:看逻辑卷的分配状态。
  • vgs:看卷组里还有多少物理容量。

df 已经释放但 vgs 剩余空间没变,说明已经进入 LVM 收缩范畴。df 都没释放,优先查进程占用和 journal 日志。

第二步:用 lsof 找回“幽灵文件”

在 CentOS 终端执行:

lsof +L1 | grep deleted

如果输出了一些路径带 (deleted) 的文件,/var/log/messages (deleted),直接用 lsof 显示的 PID 去处理:

systemctl restart rsyslog

如果是 Java 进程或其它服务,可以 kill -HUP PID 让它重新打开文件,这一招能解决相当一部分空间不释放的问题。

第三步:清理 systemd journal 日志

CentOS 7 往后的系统默认把运行日志交给 journald,它占用的空间经常超乎预期,执行:

journalctl --vacuum-size=200M

只保留 200MB 日志,比手动删 /var/log/journal 安全得多,也可以设置 SystemMaxUse 限制未来日志体积,多数情况下,这一步就能释放几个 GB。

第四步:清理 yum 缓存

/var/cache/yum 是另一个空间黑洞,运行:

yum clean all
rm -rf /var/cache/yum

注意别在删完后立刻看 df 就下结论先检查有没有进程仍在使用缓存目录。

宿主机上的 qcow2 镜像不自动收缩怎么办?

这是 CentOS 虚拟机场景中最让人头疼的一点,也是最容易忽略的一环,你在虚拟机内部把空间删干净了,df 也正常了,但回到宿主机上 ls -lh 那个 .qcow2 文件,体积依然和之前一样大。

CentOS虚拟机清理后空间未释放怎么办?虚拟机磁盘空间不回收

稀疏文件原理

qcow2 和 vhd 都支持稀疏文件:文件内部只有实际写入数据的块才分配物理存储,你删除文件时,虚拟机内的文件系统把块标记为“空闲”,但 qcow2 并不知道这些块已经没用了,它会把“空闲”状态继续保留为已分配,所以宿主机层面空间不会变。

让虚拟机内支持 discard 并执行 fstrim

CentOS 7.3 以后的发行版内核都支持块设备丢弃命令,只要虚拟机磁盘接口支持 discard(如 virtio-blk 且宿主机配置开启),就可以在 CentOS 内部执行:

fstrim -v /

这个命令会通知底层存储哪些块已经空闲,宿主机上的 qcow2 随即收缩,不过要注意,使用默认的 ext4 或者 xfs 都能配合 fstrim,但如果你的虚拟机磁盘文件是 raw 格式,则通常不需要这一步,因为它本来就不含额外元数据。

用 qemu-img convert 重建镜像

如果你的宿主机没有开 discard 预算,qcow2 在 NFS 存储上,那 fstrim 大概率没用,老老实实走离线收缩路线:

systemctl poweroff 虚拟机
qemu-img convert -p -O qcow2 old.qcow2 new.qcow2

这条命令会重新复制有效数据块,丢弃所有未使用空间,转换完成后,把 new.qcow2 改名为正式镜像再启动,对于达到几十 GB 的旧镜像,收缩效果立竿见影。

使用 virt-sparsify 更省事

如果你装了 libguestfs-tools,可以离线执行:

virt-sparsify --in-place old.qcow2

它会直接处理现有镜像,不需要复制出新文件,但注意 --in-place 模式不支持 raw 格式,操作前记得备份,毕竟是对磁盘元数据的直接改写。

处理 LVM 卷时,清理后空间不释放的第二步走

在 CentOS 虚拟机里,df 和 lvs 是两个世界,如果你确认文件系统已经释放,但 LVM 卷组空间不够,说明需要手动收缩逻辑卷。

先卸载或缩小文件系统

CentOS虚拟机清理后空间未释放怎么办?虚拟机磁盘空间不回收

ext4 文件系统要在线收缩是风险操作,生产环境务必先备份,停机后用启动盘或 live 环境操作更稳妥,重点流程:

umount /dev/centos/root
e2fsck -f /dev/centos/root
lvreduce -L 50G /dev/centos/root
resize2fs /dev/centos/root

XFS 只支持收缩,不支持在线缩小,所以只能在卸载状态下操作,这里要格外留意,别一删文件就让 LVM 自动收缩它永远不会自动动。

收缩物理卷

逻辑卷收缩以后,卷组的剩余空间还是游离的,如果需要让整块物理磁盘腾出空间给宿主机,继续跑:

pvdisplay
pvmove /dev/sda2 /dev/sda1
pvresize --setphysicalvolumesize 50G /dev/sda2

做完这些,虚拟机的底层块设备才真正瘦下来。

Q&A:CentOS 虚拟机清理后空间不释放的常见疑问

问:为什么重启 CentOS 虚拟机后,df 空间还是没增加?

重启能解决一部分被进程占用的文件,但如果是 qcow2 稀疏文件或 LVM 未缩减,重启完全无效,需要按上面步骤先查 lsof 或 journald,再处理 LVM 和镜像文件层。

问:fstrim 与 qemu-img convert 哪个更好用?

两个方案解决不同层次的问题,fstrim 只适合宿主机支持并开启 discard 的稀疏文件场景,速度快,不用停机;qemu-img convert 不依赖宿主机配置,但需要关机,重建镜像耗时较长,对于普通 CentOS 虚拟机,优先尝试 fstrim,不行再离线转换。

问:virt-sparsify 会不会损坏数据?

正常执行不会损坏数据,但任何改写磁盘元数据的行为都有风险,建议在操作前复制原 qcow2 文件备份,或者至少确认文件系统已 umount,对缺少经验的新手来说,它远比直接用 qemu-img 安全,但对生产环境仍然建议先做快照。

CentOS 虚拟机清理后空间不释放,本质上就是文件系统、LVM 和虚拟化镜像三层之间的“空间翻译”出现了延迟,删文件只是第一步,真正让空间回到宿主机,还要靠 fstrim、lvreduce 和镜像重建这一套组合拳。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱