df 满而 du 找不到大文件:用 lsof +L1 定位并释放已删除文件

举报
yd_246123679 发表于 2026/11/11 11:49:39 2026/11/11
【摘要】 df 显示磁盘已满但 du 找不到大文件时,常见原因是被删除却仍被进程打开的文件占用块。本文用 lsof +L1 定位,通过 /proc/PID/fd 截断释放,并用 df 验证回收效果。

现象:df 说满,du 说没满

在 Linux 上常遇到一种矛盾现象:df -h 显示某个文件系统接近 100%,但进入挂载点执行 du -x -h --max-depth=1,却找不到对应大小的大文件。直接 rm 一个已经被删除的文件也通常无效,因为目录项已经不存在。

这类问题常见原因是:文件已被删除,但仍有进程持有它的文件描述符。目录项删除了,inode 和已分配的数据块没有释放,df 仍会统计这些块;du 遍历目录时看不到已删除文件,所以对不上。

原因:inode 被删,fd 还开着

Linux 文件的生命周期由目录项和打开的文件描述符共同决定。执行 rm 只删除目录项;如果进程还打开着该文件,inode 的链接数变为 0,但数据块要等最后一个 fd 关闭后才释放。此时文件在 /proc/PID/fd/ 下仍可见,名称通常带有 (deleted) 标记。

排查命令是 lsof +L1。其中 +L1 表示筛选链接数小于 1 的打开文件,正好对应已删除但仍被打开的文件。也可以直接查看:

lsof +L1
lsof +L1 -p PID
find /proc/PID/fd -lname '*deleted*'

lsof +L1 输出中的 PID、FD、SIZE/OFF、NAME 可用于确认进程和文件。若系统没有安装 lsof,可用 find /proc/PID/fd -lname '*deleted*' 作为替代。

最小复现与释放示例

下面脚本在临时目录创建一个占位大文件,让一个进程打开它,再删除目录项,模拟“已删除但仍打开”的场景。示例中的 64MB 仅为演示值,可按环境调整。

set -eu
work=$(mktemp -d)
f=$work/demo.log
dd if=/dev/zero of=$f bs=1M count=64 status=none

tail -f $f >/dev/null 2>&1 &
pid=$!
sleep 1
rm -f $f

# 查看链接数为 0 的打开文件
lsof +L1 -p $pid || true

# 找到该进程下带 deleted 标记的 fd
fd_path=$(find /proc/$pid/fd -lname '*deleted*' -print -quit)
ls -l $fd_path

# 通过 fd 路径截断文件,释放数据块
truncate -s 0 $fd_path

# 验证同一文件系统的可用空间
df -h $work

kill $pid
rm -rf $work

运行方法:将脚本保存为 demo.sh,在测试环境的 Linux 主机执行 bash demo.sh。需要具备访问 /proc/$pid/fd 的权限,通常为 root 或同一用户;容器场景要进入对应 PID 命名空间查看。lsof 未安装时不影响后面的 find 路径。

核心释放动作是:

truncate -s 0 /proc/PID/fd/FD
df -h /目标挂载点

/proc/PID/fd/FD 是指向原 inode 的符号链接,truncate 会跟随链接把文件截断为 0,已分配数据块随之释放。进程仍持有 fd,但后续写入行为取决于进程实现。

边界与限制

第一,lsof +L1 只解决“已删除但仍打开”这一类问题。若没有输出,应检查 inode 是否耗尽(df -i)、是否有快照或保留块、是否有挂载覆盖、是否有未删除但被进程占用的大文件。

第二,truncate 不是无条件安全操作。对日志文件,优先使用日志轮转或让进程重新打开文件;对数据库数据文件、正在追加写入的关键文件,直接截断可能造成数据损坏或稀疏文件。执行前应确认 PID、FD、文件用途,并评估业务影响。

第三,直接 rm 已删除文件会报“No such file or directory”;对未删除文件执行 rm,只要进程还持有 fd,空间同样不会立即释放。正确顺序是先定位 fd,再选择关闭进程、轮转日志或截断。

第四,df 验证时应对准同一挂载点,避免把其他文件系统或临时目录的空间变化误认为回收成功。生产环境操作前先记录 df -h、lsof +L1 输出,操作后再对比可用空间。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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