lsof +L1:排查已删除但仍占用磁盘的文件
用 lsof +L1 定位已经 unlink 但仍被进程持有的文件,解释 df 很满而 du 找不到对应空间的常见原因。
#howto
#growing
#ops
#linux
#linux
[!info] related notes
- 总体流程:Linux 磁盘占用检查与分析
- inode / link:Linux 硬链接 / 软链接 / inode
- 进程:Linux 进程与任务控制命令
lsof +L1:排查已删除但仍占用磁盘的文件
核心问题
Linux 中:
rm file.log
主要是删除目录项(unlink),并不保证数据块立即释放。
如果进程仍持有这个 inode 的打开文件描述符:
文件名已经看不到
进程仍然在写
磁盘块仍然占用
于是会出现典型现象:
df -h → 文件系统很满
du -sh / → 目录总和明显更小
这类空间常被称为 deleted-open file / 幽灵磁盘占用。
核心命令
sudo lsof +L1
+L1 表示筛选 link count 小于 1 的打开文件,也就是通常已经被 unlink、但仍被进程占用的文件。
输出重点:
COMMAND
PID
USER
FD
SIZE/OFF
NAME
NAME 常出现:
/var/log/app.log (deleted)
只看较大的 deleted-open 文件
sudo lsof +L1 | awk 'NR==1 || $7 > 104857600 {print}'
这里以约 100 MiB 为阈值。
注意:lsof 的列布局会随对象类型变化,复杂自动化更适合使用 -F machine-readable 输出,而不是永久依赖固定 $7。
修复原则
最优:让持有 FD 的进程正常关闭文件
通常是:
sudo systemctl restart <service>
或应用自身支持的:
reopen logs
log rotation signal
graceful reload
进程关闭最后一个文件描述符后,文件系统才真正回收数据块。
不要重复 rm
文件已经被 unlink,再执行 rm 没有意义。
不要随便 kill -9
先判断:
哪个进程
为什么还持有文件
是否可以 graceful restart
是否有业务状态
常见来源
- 日志被手工
rm,但服务没有 reopen; - logrotate 配置不正确;
- Java / Node / Python 应用长期持有旧日志;
- 数据库临时文件;
- 已删除但仍打开的大型下载或缓存。
与 inode 的关系
文件是否真正释放由:
目录链接数
+
打开文件描述符引用
共同决定。
这也是理解 Unix “文件不是单纯的路径名”的一个典型案例。
排障位置
推荐把 lsof +L1 放在这个阶段:
df / duf 发现空间异常
→ gdu / du 下钻
→ 目录总和解释不了 df
→ lsof +L1
来源
- lsof 官方 man page:https://github.com/lsof-org/lsof/blob/master/docs/manpage.md