文章总结: 文档记录了一次磁盘空间报警的应急处理过程,运维人员发现Java微服务因部署脚本缺陷频繁重启,在/tmp目录下累积了6万多个hsperfdata小文件,导致磁盘空间和inode同时耗尽。通过删除残留文件、修复脚本循环重启问题、添加定期清理任务解决。关键教训是排查存储问题时应优先使用df-i命令快速识别小文件耗尽inode的情况。 综合评分: 91 文章分类: 应急响应,实战经验,安全运营,终端安全,其他
6万个小文件撑爆了Inode,我在周五下班前差点崩溃
原创
刘军军 刘军军
运维星火燎原
2026年5月20日 00:00 山西
在小说阅读器读本章
去阅读
下午4:50,监控报警,磁盘96%。
那台机器是跑一个 Java 微服务的,业务量不大但比较关键。我一边 ssh 一边想,多半又是哪个同事把大文件丢 /tmp 忘了删。
[root@euler-app01 ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/vda1 98G 94G 4.0G 96% /
还真是。我赶紧敲 du 看看到底谁最占空间:
[root@euler-app01 ~]# du -sh /* 2>/dev/null | sort -rh | head -10
3.6G /usr
2.3G /var
1.9G /home
1.2G /opt
988M /root
...
这几个加起来也就 10G 左右,跟 94G 完全对不上。我又试了一遍 du -sh /,这次不加过滤,结果一样:
[root@euler-app01 ~]# du -sh /
3.6G /usr
2.3G /var
...
明显不对。我心想,难道是有进程占着已删除文件没释放?这种情况用 lsof 能查出来。
[root@euler-app01 ~]# lsof | grep deleted | head -20
java 27341 root 12w REG 253,0 20971520 123456 /app/logs/error.log (deleted)
java 27341 root 13w REG 253,0 10485760 123457 /app/logs/access.log (deleted)
java 27342 root 12w REG 253,0 15728640 123458 /app/logs/error.log (deleted)
...
确实有不少。我直接把这几个 Java 进程重启了一下:
[root@euler-app01 ~]# systemctl restart app-service
[root@euler-app01 ~]# lsof | grep deleted | wc -l
12
还剩一些,但已经少了很多。再看 df -h:
[root@euler-app01 ~]# df -h
/dev/vda1 98G 78G 20G 80% /
降到了 78G,还有接近 70G 不知所踪。这就奇怪了——lsof 释放了大概 16G,但离最初的 94G 还差一大截。
我怀疑是不是 /proc 或者某些挂载点下面的内容被 du 忽略了。又试了 du -sh --exclude=/proc --exclude=/sys /,结果几乎没有变化。
这时候天已经黑了,办公室就剩我一个人。我有点烦躁,重新敲了一遍 du -sh /* 2>/dev/null | sort -rh,这次没有 head,而是让结果全部输出。我一行一行往下翻,翻到快最后的时候,突然看见一行:
67G /tmp
第一次跑的时候 /tmp 这行被挤到第 23 行,我根本没看到。
赶紧进去看看:
[root@euler-app01 ~]# cd /tmp
[root@euler-app01 tmp]# ls -la | head -20
total 24
drwxrwxrwt 9 root root 4096 May 19 17:32 .
drwxr-xr-x 19 root root 4096 Mar 10 2024 ..
drwxr-xr-x 2 root root 4096 May 19 16:01 hsperfdata_root_27341
drwxr-xr-x 2 root root 4096 May 19 16:02 hsperfdata_root_27342
drwxr-xr-x 2 root root 4096 May 19 16:03 hsperfdata_root_27343
...
全是 hsperfdata 开头的目录。数一下有多少:
[root@euler-app01 tmp]# ls -d hsperfdata_* | wc -l
64321
六万多个目录。每个目录里基本都有一个几 KB 的文件:
[root@euler-app01 tmp]# ls -l hsperfdata_root_27341/
total 8
-rw------- 1 root root 4096 May 19 16:01 27341
文件不大,但架不住数量多。这时候我突然想到一个命令——df -i,看 inode 的。
[root@euler-app01 tmp]# df -i
文件系统 Inodes 已用(I) 可用(I) 已用(I)% 挂载点
/dev/vda1 6.4M 6.3M 0.1M 98% /
果然,inode 也快用完了。磁盘空间被这些小文件撑满,同时 inode 也被耗尽,两个指标都爆了。
至于为什么会生成这么多 hsperfdata,后来查了历史,是因为那个 Java 服务的部署脚本有个 bug,每两小时会检测一次健康状态,检测失败就重启。每次重启都会在 /tmp 下新建一个 hsperfdata 目录,但是退出时没有正确清理。跑了几个月,就堆了六万多个。
恢复业务很简单,直接删:
[root@euler-app01 tmp]# rm -rf hsperfdata_*
[root@euler-app01 tmp]# df -h && df -i
/dev/vda1 98G 31G 67G 32% /
/dev/vda1 6.4M 1.2M 5.2M 19% /
然后我改了两处:一是修了部署脚本,不让它频繁重启;二是在 crontab 里加了一周清理一次 /tmp/hsperfdata_* 的任务。
后来跟同事复盘,我说这次最大的失误就是一开始没看 df -i。要是早几分钟敲这个命令,看到 inode 满了,就能立刻想到是小文件的问题,不会在 du 的输出里翻来翻去找半天。这个教训估计我能记好几年。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:运维星火燎原 刘军军 刘军军《6万个小文件撑爆了Inode,我在周五下班前差点崩溃》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论