不少运维新手都遇到过这样的怪现象:用 df -h 查看,磁盘明明还有几个G的空闲,可往服务器上写文件时却报 No space left on device。把临时文件清了一遍又一遍,问题依旧。这时候最需要怀疑的,往往不是磁盘容量,而是文件系统里的 inode 被用光了。

什么是inode,为什么会耗尽
inode(索引节点)是Linux文件系统用来保存文件元信息的数据结构,记录着文件的权限、属主、大小、时间戳以及数据块位置。每个文件或目录都要占用一个inode。也就是说,一个分区上到底能存放多少个文件,由inode数量决定,而不是只由容量决定。
创建文件系统时(比如 mkfs.ext4),系统会按默认比例分配inode数量。日常使用中,如果产生了海量的小文件,例如程序日志、缓存碎片、邮件队列、图片缩略图等,文件总数会迅速逼近inode上限,于是出现容量充足但无法新建文件的怪象。
如何判断inode是否已经耗尽
先用 df -i 查看各个分区的inode使用率。如果 IUse% 接近100%,说明inode接近耗尽;如果报错涉及无法创建文件,同时 df -i 显示100%,基本可以确诊。
df -i
df -ih # 以易读单位显示
# 单独查看根分区
df -i /
另外也可以用 stat 查看单个目录的inode占用情况,定位到具体目录后再逐层排查:
stat /
ls -di /tmp
inode耗尽的常见原因
- 日志文件过多且未做轮转切割,每个日志文件本身又频繁产生大量小日志;
- 程序缓存、临时目录里堆积了大量微小文件(如PHP session、图片裁剪缓存);
- 邮件系统、消息队列在异常时产生海量小文件;
- 文件被进程占用,rm删除后空间与inode迟迟不释放;
- 目录里存在隐藏的垃圾文件,比如挖矿程序或木马写入的临时脚本。
清理方法:定位并删除无用的小文件
先找出文件数量最多的目录,再决定清理对象。可以用 find 统计各一级目录下的文件数量:
# 统计根目录下各子目录的文件数量(不跨文件系统)
find / -xdev -type f | cut -d/ -f2 | sort | uniq -c | sort -rn | head
定位到嫌疑目录后,进一步看其中的文件构成。比如清理超过90天未修改的日志类文件前,建议先备份或确认业务影响:
# 查看指定目录下文件数量与占用
ls /var/log | wc -l
du -sh /var/log
# 示例:删除 /var/log 下超过30天的 .log 文件(请按实际情况调整)
find /var/log -name "*.log" -mtime +30 -type f -delete
如果确认是程序缓存或session目录堆积,一般可以直接清空目录内容,同时让服务重新生成。清空后及时验证服务是否正常:
# 清空目录但保留目录本身
find /tmp/session -mindepth 1 -delete
# 确认inode使用率已下降
df -i
还需要留意一种情况:删除后 df -i 仍然显示100%。这通常说明有进程还握着已删除文件的句柄,重启相关服务或进程即可释放。
根本解决:扩容或调整inode数量
清理只是应急手段。如果业务本身就会长期产生大量小文件,建议从架构上解决。inode数量在创建文件系统时确定,运行中的文件系统无法直接增加inode,可行的方案包括:改用支持按需分配inode的文件系统(如xfs);重新mkfs并显式指定 -i 参数增大inode比例(操作前务必完整备份数据);或者把海量小文件迁移到对象存储,用低频访问策略降低成本。
对于云服务器,最稳妥的长期做法是给数据目录单独挂载容量更大的数据盘,与系统盘隔离,避免业务文件挤占系统分区inode。
相关问答FAQs
- 问:df -h有空间但写文件报错,一定是inode问题吗?答:不一定,还可能是磁盘只读、目录权限或文件系统错误,可结合 df -i、mount 输出和 dmesg 一起判断。
- 问:删除大量小文件很慢怎么办?答:尽量用 find -delete 或 rsync –delete 的方式,比逐条 rm 更快;删除前先评估业务影响。
- 问:xfs文件系统怎么查看inode?答:xfs默认动态分配inode,一般不易耗尽,可用 df -i 查看当前使用情况。
总结一下:遇到写文件报错,先 df -i 确认inode使用率,再定位小文件最多的目录并清理;若业务长期大量产生小文件,则要考虑更换文件系统或把数据迁移到对象存储。保持日志轮转、定期清理缓存,才能避免问题反复出现。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!