首页/系统/Linux 运维命令速查/场景:inode 耗尽排查(No space left on device)
磁盘与文件系统51 条

场景:inode 耗尽排查(No space left on device)

磁盘还有空间却报 no space left on device,多半是 inode 用尽:海量小文件(session、缓存、邮件队列)是元凶。

Linux 运维命令速查系统更新于 2026-10-13

场景概述

报 No space left on device 时,第一反应通常是查磁盘空间,但 ext4、xfs 这类文件系统的 inode 数量在创建时就已经确定,用尽之后即使还有大把空闲块,也无法再创建任何新文件——日志写不进去、会话文件建不出来、程序报错方式与磁盘满完全一样。这类问题的特征是容量指标正常而 inode 使用率接近 100%,且元凶几乎总是某几个目录里堆积了海量小文件。

场景信息

触发条件有可用空间但创建文件失败,应用报 No space left on device
排查目标确认是否为 inode 耗尽,定位消耗源并清理
工具链df -i 定文件系统 → du --inodes 定目录 → find 定文件 → 分批清理
关键区别块空间与 inode 是两套独立资源,各自的告警需要各自的处置方式

常见消耗源

  • PHP、Java 等应用的会话文件目录:sessions、tmp 下累积几十万到上百万个小文件
  • 邮件队列与 spool 目录:maildrop、queue 堆积大量小文件
  • 缓存与临时文件:应用把每个请求的结果落成一个小文件且没有清理策略
  • 日志目录:应用按请求或按分钟切分日志,产生海量碎片文件
  • 容器与镜像层:overlay2 与 buildkit 缓存中的元数据文件数量巨大
  • 版本控制与依赖目录:node_modules、.git 里的对象文件动辄数十万

四步排查命令

四步排查命令
# 第 1 步:确认是块空间还是 inode 用尽
df -i; df -i /var | awk 'NR==1 || $5+0>80'
# 第 2 步:按目录统计文件数,逐层下钻
du --inodes -x -d1 /var | sort -n | tail
du --inodes -x -d1 /var/lib/php/sessions | sort -n | tail
# 第 3 步:找出小文件重灾区(按目录计数)
find /var -xdev -type f -mtime +7 -printf '%h\n' 2>/dev/null | sort | uniq -c | sort -rn | head
# 第 4 步:分批清理(先确认业务影响,再动手)
find /var/lib/php/sessions -type f -mtime +2 -delete
find /var/spool/postfix/maildrop -type f -delete
# 清理量很大时降低优先级,避免拖垮业务 IO
ionice -c3 nice -n 19 find /var/tmp/cache -type f -delete

信号判读

现象结论下一步
df -h 有空间,df -i 使用率 100%inode 耗尽按文件数而非容量找目标
df -i 正常,df -h 已满块空间不足转场景「磁盘满」的流程
某个目录 du --inodes 数值异常大小文件堆积点确认业务归属后制定清理或轮转策略
删除后 inode 不下降文件仍被进程持有或删除未生效检查删除是否成功、进程是否仍在写
ext4 的 inode 总数在 mkfs 时就已确定,事后无法增加;xfs 支持动态分配 inode,因此 xfs 上很少出现这个场景。长期运行海量小文件业务时,建文件系统应显式提高 inode 密度(mke2fs 的 -i 指定每个 inode 对应多少字节,-N 直接指定总数),否则只能靠定期清理或迁移到对象存储。
清理海量文件时直接 rm 可能报 Argument list too long,或让 IO 长时间打满。用 find ... -delete 分批删除,配合 ionice -c3 与 nice 降低优先级;删除前先把目标目录缩小到确认过的范围,避免误删业务数据。
根治要改行为而不是反复救火:会话目录设定期清理任务、日志改用轮转而不是无限切分、临时文件加 TTL 策略。只清一次不调整策略,几天后同一目录会再次堆满。
监控要同时采集两套指标:块空间使用率与 inode 使用率。很多基础监控只采集 df 的块使用率,导致 inode 悄悄涨到 100% 才被发现。对小文件密集的业务目录,还应对目录内文件数量做趋势采集,提前看到增长而不是等告警。清理动作也要记入变更台账,便于事后复盘是哪个业务模块在持续产生小文件。

易错点

  • 把 inode 告警当容量告警:扩盘增加的是块空间,ext4 上 inode 数量不会因此变化,问题依旧
  • 业务高峰直接删除上百万小文件会瞬间打满磁盘 IO,应配合 ionice 与 nice 分批执行,并避开高峰
  • 只清理当前最满的目录而不改生成策略,几天后重新堆满;清理同时要加定时任务或 TTL 策略
  • 用 rm 通配符删除海量文件会报 Argument list too long,应改用 find 加 -delete
  • 清理前不确认业务归属,误删会话或队列文件会造成用户掉线与任务丢失

数据来源与参考

  • man 1 df
  • man 1 find
  • man 1 du(--inodes)
  • mke2fs 手册(-N/-i 参数)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌