Linux 创建文件时报 “No space left on device”,即使 df -h 仍显示有剩余空间,也应对失败路径执行 df -i。如果该文件系统的 IFree 为 0,说明没有空闲 inode 可用于创建新文件;再用 du --inodes 找出积累大量小文件的目录。

适用环境与前提

示例面向使用 GNU Coreutils 9.x 的 Linux,以及 ext4 等会报告 inode 统计的文件系统。本文依据官方文档整理,未在目标服务器实测。先从应用日志找出实际写入目录;在容器里报错时,先从应用所在的挂载环境检查。以下以已存在的 /var/spool/app 为例,请换成实际路径。

1. 对同一路径比较磁盘块和 inode

df -h -- /var/spool/app
df -i -- /var/spool/app

带目录参数时,df 报告该路径所在的文件系统。第一条查看可用块空间,第二条查看 inode 总数、已用量和剩余量。若应用在创建新文件时失败、块空间仍有余量且 IFree 为 0,先排查 inode 耗尽。IUse% 是百分比,判断是否已经耗尽应看 IFree。参见 GNU df 手册。

2. 从可疑目录逐层统计 inode

du --inodes -x --max-depth=1 -- /var/spool/app

--inodes 把统计单位从磁盘空间改为 inode;-x 跳过其他文件系统;--max-depth=1 只限制输出层级,子目录仍要遍历。输出中父目录的计数已包含其后代,不能把父目录和子目录的数字相加。对计数高的子目录再运行同一命令,优先核对队列、缓存和临时目录的用途及保留规则。参见 GNU du 手册。

如果扫描出现权限错误,计数可能不完整;如果这个应用目录用量不大,再对同一挂载下其他可疑目录分批检查。大目录遍历会产生元数据 I/O,避免一开始就扫描整个根目录。

3. 验证恢复,并排除其他原因

  1. 先确认文件归属和保留期,再由应用负责人按业务规则处理积压。目录计数高只能说明它值得调查。
  2. 在原失败路径重新执行 df -i,确认 IFree 回升;再使用应用自己的低影响写入检查,确认能新建文件,并核对相同错误是否复发。
  3. 如果 IFree 仍充足,核对日志中的真实路径及挂载、块空间和配额。容器还要区分绑定挂载、卷和可写层,宿主机任意目录的 df 结果不能替代失败路径的检查。

如果问题发生在容器中,可接着看如何区分 Docker 容器可写层、数据卷与日志占用。