lsof +L1 显示的 (deleted) 文件仍占磁盘空间,是因为文件被 unlink 后只要进程未关闭 fd,内核就不释放数据块;需精准定位 PID、确认文件类型与进程可重启性后,通过优雅重启或谨慎使用 gdb 强制 close 释放。

为什么 lsof +L1 显示的 (deleted) 文件实际还在占磁盘空间
Linux 中文件被 unlink()(如 rm)后,只要仍有进程打开该文件描述符,内核就不会真正释放 inode 和数据块——文件名消失、ls 看不到,但 lsof +L1 能列出这类“已删除但未关闭”的条目。磁盘空间不会回收,直到所有持有该 fd 的进程退出或主动 close()。
如何安全批量释放这些 (deleted) 占用
不能直接 kill 进程——可能中断业务;也不能指望进程自己关闭——有些长期运行的服务(如 Java 日志轮转失败、Node.js 流未销毁、rsync 临时文件残留)会持续 hold 住 fd。关键在于:精准定位 + 可控释放。
- 先用
lsof +L1 | awk '{print $2}' | sort -u提取唯一PID列表 - 对每个 PID,检查其占用的 (deleted) 文件路径和大小:
lsof -p| grep 'deleted' - 优先处理日志类(
/var/log/...)、临时目录(/tmp/...)、容器 overlay 中的 deleted 文件 - 确认进程可重启或支持热重载(如
nginx -s reload、systemctl kill --signal=SIGUSR1)再操作 - 若进程不支持优雅关闭,且空间告急,可用
gdb强制 close(高风险,仅限调试环境):gdb -p
-ex 'call close( )' -ex 'detach' -ex 'quit'
lsof +L1 的常见误判与过滤技巧
不是所有 +L1 输出都值得干预。有些是预期行为,比如 systemd-journald 的内存映射日志、Docker 容器的 /dev/pts 残留、或某些语言 runtime 的内部临时文件。盲目清理可能引发异常。
- 排除 journald:
lsof +L1 | grep -v 'systemd-journal' - 排除容器 runtimes:
lsof +L1 | grep -E -v '(containerd|dockerd|crio)' - 按大小排序看真凶:
lsof +L1 -s | sort -k7,7nr | head -20(-s启用 size 列) - 注意 FD 类型:
REG(普通文件)才真正占磁盘;CHR/FIFO/ANON不占空间
释放后空间未立即恢复?检查挂载点和文件系统特性
即使成功 close 所有 fd,df 仍显示空间未释放,大概率是以下原因:
- 文件系统为 XFS 且启用了
inode64或延迟日志,需等待 log flush,通常几秒内自动恢复 - 挂载点被 bind mount 或 overlayfs 覆盖,真实空间在底层设备上,检查
df -h .和df -h /是否指向不同设备 - ext4 使用了
delalloc特性,缓存未刷盘,可手动触发:sync && echo 3 > /proc/sys/vm/drop_caches(仅测试环境建议) - 容器场景下,宿主机
df看的是 overlay lowerdir/upperdir,需进容器df对比,或查du -sh /var/lib/docker/overlay2/*/diff
最常被忽略的是:一个 deleted 文件被多个进程同时打开——必须全部 close 才能释放。别只杀主进程,漏掉子进程或守护线程。










