磁盘还有空间却写不进去:inode 耗尽的判断与清理顺序

举报
yd_217417492 发表于 2026/11/02 08:57:26 2026/11/02
【摘要】 df -h 显示还有几十 G,服务却报 No space left on device,多半是 inode 用完了。本文说明 inode 与块的区别、如何快速定位小文件目录,以及清理时容易踩的坑。

先确认到底缺的是块还是 inode

「磁盘满了」有两种完全不同的情况:数据块用完,或者 inode 用完。前者 df -h 能看出来,后者只有 df -i 才显示:

df -h
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/vda1        40G   12G   26G  32% /

df -i
# Filesystem      Inodes  IUsed   IFree IUse% Mounted on
# /dev/vda1      2621440 2621440       0  100% /

上面这个例子块只用了 32%,inode 却 100%。这时再删大文件没用,必须减少文件个数。

每个文件、目录、软链接都占一个 inode。ext4 在格式化时就固定了 inode 总数,事后无法扩容(只能重建文件系统),所以小文件多的场景很容易先耗尽 inode。

找出是谁在制造海量小文件

按目录统计文件数,从根往下逐层收敛:

# 统计各一级目录的文件数(排除挂载点,避免跨盘)
for d in /*; do [ -d "$d" ] && echo "$(find "$d" -xdev -type f 2>/dev/null | wc -l) $d"; done | sort -rn | head

定位到具体目录后,再看文件类型和时间分布:

find /var -xdev -type f -printf '%TY-%Tm-%Td\n' 2>/dev/null | sort | uniq -c | tail -20

最常见的三类元凶:

  • 会话文件:/var/lib/php/sessions、/tmp 下的 sess_*,过期不清理。
  • 邮件队列:/var/spool/postfix 堆积成千上万个小文件。
  • 应用缓存:按 key 落盘一文件一对象的缓存目录,或日志按请求切片。

清理的正确顺序

先停掉持续写入的进程,再删,否则一边删一边生成,永远追不上:

systemctl stop php-fpm        # 举例,按实际服务替换
find /var/lib/php/sessions -xdev -type f -mtime +1 -delete
find /tmp -xdev -type f -atime +7 -delete

注意两点:-xdev 防止 find 跨到别的挂载点;-mtime 按修改时间、-atime 按访问时间,语义不同,别混用。

大量小文件时 rm 会很慢,可以先用 rsync -a --delete empty/ target/ 快速清空目录,再删空目录本身。

为什么删了文件 inode 还是没释放

如果有进程还持有已删除文件的句柄,inode 不会立刻回收。检查:

lsof +L1 | head -20

输出里 NLINK 为 0 的就是「已删除但仍被打开」的文件。重启对应进程即可释放;直接 kill -9 前先确认业务影响。

怎么避免再次发生

与其等出事,不如提前兜住:

# 监控 inode 使用率,超过 80% 告警
df -i --output=source,pcent,target | awk 'NR>1 {gsub("%","",$2); if ($2>80) print}'

再配合定期清理策略:日志用 logrotate 的 maxage,会话目录挂 tmpfs 或加定时任务,缓存目录设上限。容器环境还要注意镜像层里的小文件,docker system df 看不到 inode,得进到 /var/lib/docker 所在分区单独看。

一句话总结:df -h 正常但报 No space left,第一反应应该是 df -i,然后按目录统计文件数收敛,别急着删大文件。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。