服务器磁盘inode耗尽,df‑i排查小文件大量堆积
服务器明明还有几十 GB 空闲,写入文件时却提示 No space left on device,新手往往第一时间怀疑磁盘满了。
其实还有一种更隐蔽的情况:磁盘 inode 耗尽。
inode 是 Linux 文件系统用来记录文件元数据的索引节点,每个文件或目录都要占用一个 inode。
当磁盘上大量堆积小文件时,inode 会被快速消耗光,即使数据块还有剩余,系统也无法再创建新文件。
本文将从 inode 原理讲起,带你用 df -i 定位问题,找到小文件堆积的具体目录,并给出可直接执行的清理与预防方案。
inode 耗尽的表现与确认方法
出现 inode 耗尽时,常见现象包括:
- 程序报错
No space left on device,但df -h显示磁盘仍有余量; - 网站无法生成缓存文件、日志无法写入;
- 数据库临时文件或 session 文件创建失败;
- 执行
touch test.txt也会失败。
先用两条命令做基础判断:
df -h # 查看磁盘空间占用
df -i # 查看 inode 占用情况
如果 df -i 输出中某个挂载点的 IUse% 接近 100%,就基本确认是 inode 耗尽。
此时需要找出是哪个目录堆积了大量小文件。
定位小文件大量堆积的目录
排查思路是逐层统计目录下的文件数量,缩小范围。
常用的定位命令如下。
统计当前目录下的文件总数:
find / -xdev -type f | wc -l
逐层查看哪个一级子目录文件最多(以 / 为例):
for dir in /*; do echo "$dir: $(find "$dir" -xdev -type f | wc -l)"; done | sort -t: -k2 -rn | head
如果已经能猜到大概区域,比如是 /var 或 /www,可以直接深入统计:
find /var -xdev -type f | wc -l
find /www -xdev -type f | wc -l
找到可疑目录后,再用下面命令列出其中文件数最多的子目录,以 /var/spool 为例:
for dir in /var/spool/*; do echo "$dir: $(find "$dir" -xdev -type f | wc -l)"; done | sort -t: -k2 -rn | head
常见的小文件堆积位置包括:
/var/spool/postfix/maildrop:未发出的邮件队列,被频繁调用 mail() 函数的程序塞满;/tmp:临时文件未及时清理;/www/wwwlogs:大量历史日志未轮转;- 程序运行产生的缓存目录,如
session、cache、upload/tmp。
清理小文件的具体命令与注意事项
确认目录后,可以分情况清理。
清理邮件队列(很常见)
如果 find /var/spool/postfix -type f | wc -l 数量巨大,可以先停掉 postfix,再清空队列:
systemctl stop postfix
find /var/spool/postfix/maildrop -type f -delete
systemctl start postfix
建议先确认这是不是你要保留的邮件,再执行删除。
如果服务器需要发送邮件,别直接删除整个队列,可结合业务排查不断产生邮件的原因。
清理日志目录
只保留最近 7 天的日志文件:
find /www/wwwlogs -type f -mtime +7 -delete
日志文件建议配置 logrotate 轮转,避免单文件过大和旧日志无限堆积。
清理临时目录
find /tmp -type f -mtime +1 -delete
生产环境删除临时文件前,最好先确认没有进程正在使用这些文件,否则可能引发程序异常。
避坑指南:这些操作可能让问题更糟
- 不要用
rm -rf /系列命令直接删除整个目录,先列出文件再针对性删除; - 不要随意删除
/var/spool/postfix/maildrop下正在写入的文件,可能造成 postfix 报错,需先停止服务; - 清理前先备份关键数据,比如日志、数据库 dump 文件,防止误删后无法恢复;
- 删除文件后 inode 不会立即释放,如果文件被进程占用,即使删除了
fd仍指向旧文件。可以用lsof | grep deleted找出占用进程并重启它; - 极小的文件也可能导致 inode 爆满,例如 0 字节文件、空目录同样消耗 inode,所以别只按文件大小排查。
清理后的验证与长期预防
清理完成后,再次运行 df -i 确认使用率下降:
df -i
如果 IUse% 回到正常值,比如 80% 以下,说明问题解决。
还可以用 df -h 对比空间状态,确认系统恢复正常写入。
要避免再次出现 inode 耗尽,建议做好以下预防:
- 为
/tmp、日志目录设置定时清理任务,例如用 crontab 每日执行find /tmp -type f -mtime +1 -delete; - 启用 logrotate 管理日志轮转,而不是让日志无限增长;
- 把大量小文件(比如 session、图片缩略图)定期归档或改用合适的存储服务;
- 监控 inode 使用率,建议在 Zabbix、Prometheus 或宝塔监控中加入
df -i指标,使用率达到 80% 就告警。
如果你曾遇到磁盘空间没满但无法写入文件的报错,不妨先按上面的方法检查 inode。
定位到小文件堆积目录后,用本文给出的清理命令处理即可恢复。
如果你的环境比较特殊,比如运行着高并发服务或数据库,清理前一定要确认业务影响,并先在测试机验证命令效果。
其他常见问题比如 df -i 显示 100% 但删除后仍报错,可以优先看是否有进程持有已删除文件的句柄,使用 lsof | grep deleted 查找并重启相关服务即可。