Linux 根分区 100% 却找不到大文件?记一次 lsof 发现已删除句柄的排查
【摘要】 磁盘告警根目录被占满,但 du -sh * 统计各目录大小远小于总容量。本文记录使用 lsof 排查被删除但未释放句柄的大文件故障实战。
今天早上收到云监控告警,一台业务服务器的根分区使用率达到了 100%,导致很多应用写入日志失败。
一、诡异现象:df 满了,du 却算不出来
登录服务器执行 df -h 查看:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 50G 49G 0 100% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
然而执行 du -sh /* 2>/dev/null | sort -hr 统计所有目录大小,加起来总共只有不到 15G。凭空消失的 35G 空间去哪了?
二、排查 deleted 句柄占用
在 Linux 文件系统中,如果一个文件已经被 rm 删除了,但有正在运行的进程仍然持有该文件的打开文件描述符(FD),文件的目录项虽然被移除了,但数据块不会被释放,空间依然被占用。
执行以下命令排查带有 deleted 状态的打开文件:
lsof | grep deleted | sort -k7 -nr | head -n 10
输出立案:
java 12844 appuser 3w REG 253,1 36814291840 184521 /opt/app/logs/catalina.out (deleted)
原来是之前同事在没有重启 Tomcat 的情况下直接 rm -f catalina.out,导致进程继续往已被删除的文件描述符中写数据,这个被删的文件已经膨胀到 36GB。
三、正确释放空间与规避方案
如果业务不能立刻重启,可以通过 /proc 目录下对应的文件描述符进行安全截断清空:
# 找到 PID 12844 对应的 fd 3
echo "" > /proc/12844/fd/3
清空后立刻再次执行 df -h,根目录使用率瞬间降到了 28%,空间完美释放。
避坑准则:日常清理正在运行的日志文件时,严禁直接 rm,应当使用 echo "" > file.log 或者通过 logrotate 配合 copytruncate 机制进行平滑轮转。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)