df 说磁盘满了,du 却找不到大文件:一次 Linux 磁盘"幽灵占用"排查实录

举报
yd_297085602 发表于 2026/10/27 10:50:07 2026/10/27
【摘要】 排查 Linux 服务器磁盘问题时,最让人困惑的场面莫过于:df -h 显示分区 100%,但 du 把所有目录加起来,数字远小于分区容量。空间像被"幽灵"吃掉了。这篇文章给出一套完整的排查路径。先说结论:df 和 du 的口径本来就不一样——df 统计的是文件系统块层已分配的空间,du 统计的是还能从目录树索引到的文件。两者差值大,说明空间被"目录树之外的句柄"占着。一、第一嫌疑:已删除但...

排查 Linux 服务器磁盘问题时,最让人困惑的场面莫过于:df -h 显示分区 100%,但 du 把所有目录加起来,数字远小于分区容量。空间像被"幽灵"吃掉了。

这篇文章给出一套完整的排查路径。先说结论:df 和 du 的口径本来就不一样——df 统计的是文件系统块层已分配的空间,du 统计的是还能从目录树索引到的文件。两者差值大,说明空间被"目录树之外的句柄"占着。

一、第一嫌疑:已删除但仍被占用的文件

这是最高频的原因。典型场景:某个进程(日志服务、应用自己写的守护脚本)一直在写一个日志文件,运维用 rm 把文件删了,但进程还握着这个文件的句柄继续写。

rm 删的是目录项(文件名到 inode 的链接),只要有进程还打开着这个 inode,文件数据就仍然占着磁盘空间——而 du 顺着目录树已经找不到它了。

正确的排查命令不是 lsof | grep deleted(大机器上输出多且容易漏),而是按"链接数为 0 但仍被打开"精确过滤:

lsof +L1

输出里带 (deleted) 标记的大文件就是元凶。处理分两种情况:

情况一,进程可以重启:直接重启对应服务,句柄释放,空间立刻归还。

情况二,进程不能重启(比如生产环境的日志进程):不要 rm,用截断的方式释放内容:

> /proc/进程PID/fd/文件描述符号

注意是用重定向清空内容,不是删掉 /proc 下的链接。清空后 df 立刻恢复正常,进程继续正常写入。

二、lsof 不可用时,直接扫 /proc

最小化环境里可能没有 lsof,用 shell 遍历所有进程的 fd 目录同样有效:

for pid in /proc/[0-9]*; do ls -l $pid/fd 2>/dev/null | grep deleted; done

输出里同样能看到 (deleted) 文件和对应进程。

三、第二个嫌疑:挂载点遮蔽

现象:du 的结果和 df 差距巨大,且 lsof +L1 毫无发现。

成因:在某个大目录上又挂载了新磁盘。比如 /var 已经堆积了 80GB 旧数据,后来在 /var 上挂了新盘,旧数据被新文件系统"盖住"了——du 看到的是新盘的内容,旧数据仍然占着底层分区的空间。

验证方法是用 bind mount 绕过子挂载点看底层:

mkdir /mnt/root
mount --bind / /mnt/root
du -sh /mnt/root/var

bind 挂载根目录本身不包含子挂载点,看到的就是被遮蔽的旧数据。确认后 umount /mnt/root,再决定旧数据怎么清理。

四、三个次常见原因

1. 文件系统预留块。ext4 默认给 root 用户预留 5% 的空间,小盘上这 5% 很可观。查看:tune2fs -l /dev/vda1 | grep -i reserved。生产盘可以考虑用 tune2fs -m 1 把预留比例降到 1%。

2. inode 耗尽。df -h 显示有空间,但写入报 No space left。用 df -i 检查 IUse%,100% 时删除大量小文件(邮件队列、session 文件、缓存碎片是重灾区)。

3. 稀疏文件。对比 du -h 和 du -h --apparent-size,后者按逻辑大小统计。数据库裸设备、虚拟机磁盘镜像常是稀疏文件,du 的口径更接近真实占用量。

五、根治:让这类问题不再发生

排查是治标,三个习惯治本:

1. 日志统一接 logrotate,用 copytruncate 模式或 postrotate 钩子里 reload 进程,从机制上杜绝"删了文件进程还在写"。

2. 挂载新盘前先检查目标目录是否已有大量数据,有则先迁移再挂载,避免遮蔽。

3. 部署基础的磁盘监控(任何监控体系都有现成的 node_exporter 文件系统指标),对 df 口径的使用率做告警,别等 100% 才上服务器救火。

六、排查清单(存下来下次直接用)

第一步 lsof +L1 找幽灵文件;
第二步扫描 /proc 找 deleted 句柄;
第三步 bind mount 检查挂载点遮蔽;
第四步查预留块、inode、稀疏文件;
第五步上监控和日志轮转,根治复发。

按经验,十例里七八例倒在第一步:lsof +L1 一跑,那个隐形占用者就现形了。如果你正被这个问题困住,现在就开个终端试第一条命令。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。