磁盘明明还剩很多空间,写文件、甚至 touch 一个空文件都报 No space left on device?先给结论:
磁盘没满,是 inode 用尽了。 Linux 每个文件/目录都要占用一个 inode(索引节点),一个分区能创建的 inode 总数有限。当小文件多到把 inode 吃光,即便块空间还有富余,也无法再新建任何文件。
第 1 步:确认是不是 inode 耗尽
df -i 看 inode 使用率,而不是 df -h 看空间:
df -i /
看 IUse% 一列。如果接近 100%,基本可以确定是 inode 耗尽。
# 只看根分区
df -i / | head
# Filesystem Inodes IUsed IFree IUse% Mounted on
# /dev/sda1 655360 655360 0 100% /
提示:
df -h看的是块(Block)空间,df -i看的是inode(索引节点),两者都满都会导致"无法写入",需分别检查。
第 2 步:找出小文件堆在哪
最常见来源:邮件队列、/tmp、缓存目录、程序产生的海量小日志或 session 文件、journald 高频写入等。逐层找 inode 占用大的目录:
# 找到 inode 数最多的顶层目录
find / -xdev -printf '%h\n' 2>/dev/null | sort | uniq -c | sort -rn | head
# 更直观:逐层统计,进入可疑目录继续
for d in /var /tmp /home; do echo "$d: $(find $d -xdev -type f 2>/dev/null | wc -l)"; done
或按目录树从上到下找 inode 大户:
du --inodes -x --max-depth=1 / 2>/dev/null | sort -rn | head -20
提示:
du --inodes需要 GNU coreutils 较新版本(Debian 较新 / RHEL 8+ 一般可用)。若提示不支持,就用上面的find ... | uniq -c思路。
第 3 步:针对海量小文件清理
定位到目录后,查看里面是什么再清理。清空目录下大量小文件示例(注意先确认目录用途,别误删数据):
# 例:清空 session/临时文件目录下的内容(先看,再清)
ls /tmp/sess_* | head # 先看看是什么
find /tmp/sess_* -type f -delete # 删除(确认无误后)
# 大日志先清空内容(省 inode 不释放也没关系)
sudo truncate -s 0 /var/log/app.log
清理后确认 inode 使用率下降:
df -i /
如果确实需要更多 inode
- 重新 mkfs 时加大 inode:只有分区未用/可重新格式化时才可行(会丢数据,谨慎),
mkfs.ext4 -N 数量或指定-i bytes-per-inode预留更多 inode。 - 把海量小文件目录放到 inode 充足的分区,或改用能承载海量小文件的存储(如换到 inode 预算更高的文件系统)。
- 多数场景靠清理就能解决,扩容 inode 是在清理也满足不了时的下策。
日常预防
- 对会堆积小文件的目录做定期清理 + 日志轮转,别让小文件无限增长。
- 用
df -i纳入日常巡检;结合同系列"磁盘增长定位"识别异常目录。
FAQ
问:df -h 明明有空间,为什么还报 no space?
可能是 inode 耗尽。用 df -i 看 inode 使用率即可区分"块满"与"inode 满"。
问:inode 满了怎么快速定位小文件在哪?
du --inodes -x --max-depth=1 / | sort -rn | head 逐层找目录;再进到可疑目录缩小范围。
问:不删数据能给分区扩容 inode 吗? 运行中的分区一般不能直接扩 inode;通常靠清理小文件解决,或把堆积目录迁到 inode 更充足的分区/文件系统。
问:inode 数怎么看总共多少、还能用多久?
df -i / 的 Inodes 与 IFree 两列即总量与剩余;IUse% 越接近 100% 越危险。
想区分磁盘空间去向,可看同系列:df/du 不一致、磁盘满了删不掉、磁盘清理实战。