磁盘空间未释放是因已删除但被进程占用的文件,可用lsof +L1查找deleted条目,按大小排序定位大文件,通过重启进程、日志重载或谨慎清空/proc/PID/fd/方式释放,并配置logrotate和定期巡检预防。

这种情况通常是因为有已删除但仍在被进程占用的文件,导致磁盘空间未被释放。df 显示 100%,而 du 统计总和远小,说明“看不见”的文件占用了大量空间。
确认是否存在被删除但仍被打开的文件
运行以下命令查看被删除但未释放的文件:
lsof +L1 或 lsof | grep deleted
输出中会列出类似 /var/log/syslog (deleted) 的条目,这些就是罪魁祸首。重点关注大文件(看 SIZE 列或用 lsof -n | grep deleted | sort -k7 -hr | head -20)。
定位占用空间最多的进程和文件
结合 lsof 和文件大小排序快速定位:
-
按文件大小倒序查看所有被打开的 deleted 文件:
lsof -n +L1 -s | awk '{if($7~/[0-9]+[KMG]/) print $0}' | sort -k7,7hr | head -10 -
查看某进程打开的所有文件(含 deleted):
lsof -p PID(替换为实际 PID) -
检查 /proc 下对应进程的 fd 目录是否包含大 size 的 deleted 链接:
ls -lh /proc/PID/fd/ | grep deleted
释放被占用的空间
只有让对应进程释放文件句柄,空间才会真正回收:
-
若进程可重启:直接
systemctl restart 服务名或kill -TERM PID(优雅终止) -
若进程不能停(如数据库、Java 应用):尝试其内置日志轮转或 reload 操作(如
kill -USR1 PID触发某些服务重开日志) -
极端情况(不推荐):手动清空 /proc/PID/fd/N(需 root),例如:
echo > /proc/PID/fd/12(仅适用于可截断的文件,且存在风险,务必确认文件用途)
预防与日常检查
避免问题反复发生:
- 配置 logrotate 并确保 postrotate 脚本正确通知服务重新打开日志
- 监控
lsof +L1输出频率,加入巡检脚本 - 对长期运行的服务,定期检查其日志路径和 open files 状态:
find /var/log -xdev -type f -size +100M -ls 2>/dev/null - 使用
du -shx /* 2>/dev/null | sort -hr替代du -sh /\*(-x避免跨文件系统误统计)










