服务器磁盘告警后,你找到一个几十GB的日志文件,执行删除,目录里已经看不到它,df -h却几乎没有变化。继续删除别的文件风险越来越大,业务也可能被误伤。
最常见的原因是进程仍然打开着这个文件。Linux目录项已经删除,进程手里的文件描述符还在,内核会继续保留数据块,直到进程关闭句柄。先用df和du确认差值,再决定是否重启或让服务重新打开日志。

第一步:确认满的是哪个文件系统
执行:
df -hT
df -ih
df -hT看容量和文件系统类型,df -ih看inode。磁盘容量没满但inode达到100%,通常是大量小文件,不是一个大日志占用。
记住告警对应的挂载点,例如/、/var或独立数据盘。不要在根目录直接执行无边界删除命令。
假设满的是/var:
sudo du -xhd1 /var | sort -h
sudo du -xhd1 /var/log | sort -h
-x限制在当前文件系统,避免跨到其他挂载点。逐层进入最大的目录,不要一开始扫描整个系统并把输出混在一起。

如果df显示已用200GB,du只能找到120GB,80GB差值值得继续查已删除文件、快照、保留块和挂载覆盖。
执行:
sudo lsof +L1
重点看COMMAND、PID、SIZE/OFF和NAME。名字末尾常出现(deleted)。
也可以按大小筛选:
sudo lsof +L1 | sort -k7 -n
不同lsof版本列位置可能不同,排序结果只作辅助。最可靠的是确认进程、文件路径和占用量。

出现大文件后不要立即kill -9。先确认进程属于哪个服务:
ps -fp <PID>
systemctl status <服务名>
处理顺序建议:
-
查看服务是否支持重新打开日志,例如reload或专用信号。 -
有维护窗口时执行`systemctl restart <服务名>`。 -
重启后马上检查服务状态、监听端口和业务健康。 -
再执行`df -hT`确认空间是否释放。
服务重启会中断连接或任务。数据库、消息队列和存储服务不能只为释放空间就随意重启。先读服务文档,确认高可用、维护窗口和回滚方法。
有人会向/proc/<PID>/fd/<FD>写入空内容来释放空间。这个方法可能破坏程序预期的写入位置和日志结构,不适合作为通用教程。优先让服务按自身机制关闭并重新打开日志。
journalctl --disk-usage
sudo journalctl --vacuum-time=14d
先看占用,再按时间或大小清理。不要直接删除/var/log/journal中的活动文件。完成后配置SystemMaxUse等限制,避免反复告警。
Docker默认JSON日志可能增长很快:
sudo find /var/lib/docker/containers -name '*-json.log' -size +1G -ls
先确认容器和日志驱动,再配置max-size、max-file或集中日志。不要在业务运行时盲目删除容器目录。
ext文件系统可能为root保留部分空间;LVM、ZFS、Btrfs或云盘快照也可能保留数据。普通目录du看不到所有占用,需要使用对应工具检查。
某目录写入数据后又挂载了另一块盘,原目录里的文件会被遮住。卸载查看会影响业务,必须在维护窗口操作。可以先用findmnt确认挂载关系:
findmnt

修复后要补上防复发
只释放空间还不够。根据日志来源补上轮转和上限:
-
`logrotate`设置轮转周期、保留数量、压缩和服务重开日志方式。 -
journald设置磁盘上限。 -
Docker设置日志驱动和单文件上限。 -
监控同时观察容量、inode和增长速度。 -
告警预留处理时间,不要等到100%才处理。

-
`df -hT`确认文件系统,`df -ih`排除inode满。 -
`du -xhd1`逐层找可见文件。 -
`lsof +L1`找已删除但占用的文件。 -
用服务支持的reload或维护窗口重启关闭句柄。 -
复查服务健康和`df`空间。 -
没有deleted文件时查journal、容器日志、快照、保留块和挂载覆盖。 -
配置轮转、上限和增长告警。
删除文件只是去掉目录入口。进程何时关闭句柄,才决定数据块何时真正归还文件系统




