首页/系统/Linux 运维命令速查/场景:删除文件后空间不释放
磁盘与文件系统51 条

场景:删除文件后空间不释放

df 显示满、du 找不到大文件——典型是已删除但进程仍持有句柄的文件;定位并安全释放。

Linux 运维命令速查系统更新于 2026-10-13

场景概述

现象很好认:df 显示某挂载点持续接近 100%,du 从根目录逐层统计却找不到对应的大文件,同时应用仍在正常运行、日志仍在写入。原因是文件删除只摘掉了目录项,进程手里的文件描述符仍指向原来的 inode,只有最后一个句柄关闭,数据块才会被回收。这类占用在 du 的视野之外,却在 df 的统计之内,是容量排查中最典型的「看不见的占用」。

场景信息

触发条件rm 之后 df 没有下降,空间告警持续存在
排查目标找出被持有的已删除文件与持有进程,并用最小代价释放空间
工具链df 确认差异 → lsof +L1 列出已删除文件 → /proc/PID/fd 交叉验证 → 重载或重启进程
判据df 已用明显大于 du 合计,且 df 仍在上涨,通常是日志类文件被删除但进程未重开

常见来源

  • 日志被误删:logrotate 配置错误或人工 rm 掉了正在写的日志文件,应用句柄仍然有效
  • 临时导出文件:备份与导出任务产生的大文件被删除,但任务进程还没退出
  • 容器场景:容器内删除文件后宿主机的 overlay 层仍持有,容器运行时日志文件被删同理
  • 数据库与中间件:WAL、binlog 或临时段文件被清理但进程未释放句柄
  • 脚本误判:清理脚本按名字删除后又重新创建同名文件,旧句柄继续写入旧 inode

排查与处置命令

排查与处置命令
# 第 1 步:列出 link count 为 0 的已删除文件,按大小排序
lsof +L1 2>/dev/null | sort -k7 -n | tail -n 20
lsof -nP +L1 | awk '$7>1073741824 {print}'      # 只关注大于 1GiB 的
# 第 2 步:交叉验证持有进程与句柄
ls -l /proc/<PID>/fd | grep deleted
ls -l /proc/<PID>/fdinfo/<FD>
# 第 3 步:处置——首选让应用重开文件
systemctl reload <服务>          # 支持平滑重载的优先用 reload
systemctl restart <服务>         # 不支持时重启,提前确认业务影响
kill -HUP <PID>                  # 很多服务收到 HUP 会重开日志文件
# 第 4 步:确认空间释放
df -h; lsof +L1 | head

判据与处置对照

现象结论处置
df 满而 du 找不到大文件存在被持有的已删除文件用 lsof +L1 确认
lsof +L1 列出 (deleted) 条目确认持有进程与文件大小按业务重要性选择重载或重启
/proc/PID/fd 中同一天有 deleted 条目该进程正在写已删除文件重开日志文件或重启进程
重启后空间仍不下降还有别的进程持有,或占用来自容器分层扩大排查范围,检查容器与宿主层
lsof 的 +L1 表示「链接数小于 1」,即文件已没有目录项指向它。全量 lsof 输出可能几十万行,先用 +L1 收窄再按 SIZE 列排序,能直接看到最占空间的那几个句柄;也可以在 /proc/*/fd 上按 deleted 关键字扫描,速度更快但需要自己解析。
让应用重新打开日志文件是首选处置:支持信号的服务收到 HUP 会重开;有 ExecReload 的单元用 systemctl reload;两者都不支持再考虑 restart。对数据库这类进程,重启前必须确认复制状态与业务低峰,硬重启带来的恢复时间往往比多做几步确认更长。
「把这个文件再 rm 一次」对 deleted 句柄无效,目录项已经不存在。另外,若应用持有的句柄没有用追加方式打开,重建同名文件并截断后,旧句柄仍会按原偏移写入,产生一个占用巨大但对不上实际内容的空洞文件,这类文件在 du 与 ls -l 的读数上也会明显不一致。

易错点

  • 对被持有的已删除文件再执行 rm 是无效操作,空间不会释放,必须让持有进程关闭句柄
  • 只对应用做日志截断而不重启或重载,旧句柄可能按原先的偏移继续写入,形成大小异常的空洞文件
  • 对数据库、消息队列这类有状态服务直接 kill -9,恢复与一致性校验的代价远高于先做完整评估
  • 只清空间不查根因(为什么文件会被删除、为什么进程不重开文件),同类问题会在下个周期重复出现
  • lsof 不加过滤直接执行,几十万行输出既刷屏又难定位,应先 +L1 再按大小排序

数据来源与参考

  • man 8 lsof(+L1 语义)
  • proc(5) man(/proc/PID/fd)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌