lsof +L1是精准定位“幽灵文件”的唯一可靠方法,它只筛选链接计数为0的已删文件,避免grep deleted的误匹配;需加sudo执行,重点关注PID、COMMAND、FD、SIZE/OFF及(deleted)标识。

用 lsof +L1 精准找出“幽灵文件”
别信 lsof | grep deleted——它会误匹配路径里带 deleted 的正常目录(比如 /tmp/deleted_cache)。+L1 是唯一可靠过滤器,只抓链接计数为 0 的文件,也就是真被 unlink() 但 fd 还开着的那些。
必须加 sudo,否则看不到其他用户的进程:
-
sudo lsof +L1:全局扫描 -
sudo lsof +L1 /var/log:聚焦日志目录,更快 -
sudo lsof -u www-data +L1:只看特定用户
输出里重点关注四列:PID(进程号)、COMMAND(服务名)、FD(如 7w 表示写入描述符 7)、SIZE/OFF(当前占用字节数,直接对应空间黑洞大小),最后一列必须是 (deleted) 才算实锤。
释放空间前先判断:能 reload 就别 kill
很多服务支持平滑重载日志,不中断业务就能关闭旧 fd、打开新文件。硬杀进程虽快,但可能丢缓冲区日志或触发异常状态。
- Nginx:用
sudo kill -USR1或PIDsudo systemctl reload nginx - Rsyslog / Syslog-ng:用
sudo kill -HUPPID - Java 应用:如果用了 logback/log4j 且配置了
ReconfigureOnChangeFilter,可发SIGHUP;否则优先走systemctl restart - 不确定是否支持?先查服务状态:
systemctl status,看有没有myappReload操作提示
清空 /proc/PID/fd/FD 要极度小心
PID/fd/FD执行 echo > /proc/1234/fd/7 会把该 fd 对应的文件内容截断为 0 字节,立即释放磁盘块,进程还能继续写——但这只对追加模式(O_APPEND)写日志的服务安全。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
以下情况千万别用:
- 数据库进程(如 MySQL、PostgreSQL):文件长度突变可能破坏 WAL 或 checkpoint 逻辑
- 自己写的 C/Python 程序,没做
ftruncate()兼容处理 - fd 是读模式(
r)而非写模式(w或wr)
真正保险的做法永远是:systemctl restart 。只有当进程无 systemd 单元(比如手动起的脚本)、且确认无数据风险时,才考虑清空 fd。service_name
df 和 du 差值大 ≠ 一定是幽灵文件
差值明显(比如 df 显示用了 20G,du 加起来才 12G)确实高度提示有未释放句柄,但还有两个常见干扰项:
-
inode 耗尽:df -i查看,满的话报错也是No space left on device,和磁盘块无关 - 容器或 chroot 环境:
lsof +L1可能看不到宿主机外的进程句柄,得进容器 namespace 里查
最常被忽略的是:有些服务(如旧版 rsyslog)在 logrotate 后不自动重开日志,又没配 copytruncate,导致旧 fd 一直挂着——这种问题不会随时间自愈,得人工介入。










