No space left on device。df -i、du --inodes 和文件计数判断 inode 耗尽,而不是磁盘容量耗尽。Linux 虚拟机或一次性特权容器,具备 root 和 mount。实验只挂载到 /tmp/lab-inode,不触碰宿主机已有文件系统。
sudo -i
mkdir -p /tmp/lab-inode
mount -t tmpfs -o size=64m,nr_inodes=256 tmpfs /tmp/lab-inode
findmnt -T /tmp/lab-inode
df -h /tmp/lab-inode
df -i /tmp/lab-inode
nr_inodes=256 是本次实验的关键参数。确认 df -i 的 Inodes 总数约为 256 后再继续。tmpfs 的 inode 限制只影响这个挂载点,删除挂载点后自动消失。
创建大量空文件,直到 inode 用尽:
for i in $(seq 1 300); do
: > "/tmp/lab-inode/file-$i" || { echo "failed at file-$i"; break; }
done
循环应在前 260 个文件左右报 No space left on device 并退出。此时每个文件几乎不占数据块,但都消耗一个 inode。
df -h /tmp/lab-inode
df -i /tmp/lab-inode
find /tmp/lab-inode -maxdepth 1 -type f | wc -l
du --inodes -x --max-depth=1 /tmp/lab-inode | sort -n
touch /tmp/lab-inode/after-full
预期 df -h 仍显示大量可用空间,df -i 的 IUse% 为 100%,文件计数接近 inode 总数,新建文件继续报 No space left on device。
df -h 和 df -i,不要只看容量。df -h 有余量、df -i 满,就是 inode 耗尽;两者都满才是容量耗尽。du --inodes 找出小文件最多的目录,常见于缓存、session、队列和构建产物。df -h 有空间会让人怀疑应用权限或磁盘故障,实际是文件系统元数据耗尽。另一个误判是只删除大文件,但大文件释放的是数据块,不是被小文件占满的 inode。先确认这些文件可删除,再按范围清理:
find /tmp/lab-inode -maxdepth 1 -type f -name 'file-*' -delete
df -i /tmp/lab-inode
touch /tmp/lab-inode/after-full
ls -l /tmp/lab-inode/after-full
touch 成功即表示 inode 已释放。生产环境应优先处理产生海量小文件的程序,例如关闭按请求切分日志、调整缓存淘汰策略、把队列消息落到对象存储,而不是长期靠人工删除。
umount /tmp/lab-inode
rmdir /tmp/lab-inode
如果 umount 报忙,先用 lsof +f -- /tmp/lab-inode 查找占用进程。tmpfs 卸载后内容全部消失,不会影响其他挂载点。
mkfs 时固定,后期不能在线增加;容量规划时要估算小文件数量,或改用 XFS 等更适合大量文件的方案。df -h 有空间但创建文件报 ENOSPC,首先应该看哪个指标?df -i,确认 inode 是否耗尽。