df 显示还剩 40G,为什么文件就是写不进去
上周有台测试机跑批任务,凌晨两点开始报错,日志里全是 No space left on device。我早上到工位第一件事就是登上去看,df -h 一敲,根分区还有 40G 空着。
我以为 df 骗人,又跑了一遍 du -sh /*,最大的目录才 6 个 G。两边加起来对不上,可谁都没到写满的程度。
后来才想起来看 df -i。Use% 那一列是 100%,可用 inode 是 0。不是空间没了,是文件数量到顶了。
原因不难查。那个批任务每跑一次就在 /data/tmp 下建一堆小文件,正常流程结束会删,但上个月有人改了异常处理,脚本抛错直接退出,删除那一步被跳过了。一个多月下来攒了八十多万个空文件,每个占一个 inode,大小 0 字节。
空间指标一直很健康,所以监控没报。等 inode 见底,连日志都写不进去,报错的现场也存不下来。
处理没什么技巧。先按目录数文件,找出最离谱的那个:
find /data/tmp -type f | wc -l
find /data/tmp -type d | awk -F/ '{print "/"$2"/"$3"/"$4}' | sort | uniq -c | sort -rn | head
第二条按三级目录统计,一眼就看出是 tmp 下某个 batch_ 开头的目录,六十多万个文件。确认没有任务在跑之后,我分几批删的,一次删太多 rm 自己也会卡住。
删完 df -i 回到 20% 左右,服务立刻恢复。
事后做了两件事。监控里加了 inode 使用率,阈值 85%,之前只盯磁盘空间。批任务脚本里改成 trap 捕捉退出,不管正常还是异常都执行清理。
这个坑在云主机上比物理机更容易遇到。系统盘的 inode 总数是按创建时的规格算的,后期扩了盘容量,inode 不会跟着涨,只是每个 inode 能管的块变多了。所以扩容解决不了 inode 耗尽。
现在要查自己的机器就一条命令 df -i,看 Use% 那一列,比看磁盘空间更容易发现早期问题。
- 点赞
- 收藏
- 关注作者
评论(0)