VPS磁盘还有空间却无法创建文件?用inode、目录数量和临时文件定位

数据块没满不代表还能创建文件,先用 df -i 找到 inode 消耗点。
发布于
2

VPS上出现“磁盘空间不足”或应用无法创建新文件时,先不要只看 df -h。文件系统同时受数据块和 inode 数量限制:前者决定还能写入多少字节,后者决定还能登记多少个文件。当小文件、缓存片段或邮件队列数量过多时,磁盘仍可能显示有剩余容量,但新建文件会失败。

先区分“空间满”还是“inode用尽”

在授权维护窗口内,先记录挂载点、文件系统类型和两类使用率:

df -hT
df -i
findmnt -no TARGET,FSTYPE,OPTIONS /

如果 df -h 接近 100%,重点查大文件和日志;如果 df -i 接近 100%,则应查小文件数量。两者都不高却写入失败,还要考虑只读挂载、配额、权限或应用自己的临时目录已满。

inode耗尽时按目录树缩小范围

不要一上来对整个根目录执行高开销扫描。先从常见的缓存、日志、队列和容器目录开始,按一级目录统计条目数量:

for d in /var /tmp /home /opt; do
  [ -d "$d" ] && printf '%s ' "$d" && find "$d" -xdev -type f 2>/dev/null | wc -l
done

发现异常目录后,再按业务子目录分层统计。应用生成的 session、缩略图、任务分片和失败重试文件常常比单个大日志更快耗尽 inode。容器环境还应检查可写层和挂载卷,确认小文件到底属于宿主机还是容器内部。

别漏掉“已删除但仍占用”的文件

删除日志后空间没有回来,可能是进程仍持有文件描述符。用只读方式确认:

lsof +L1
# 或按挂载点缩小范围
lsof +L1 | grep '/var'

这类文件不一定造成 inode 耗尽,但会让 df -h 与目录统计不一致。应根据进程的优雅重载或重启文档释放句柄,不要直接破坏进程状态。

清理前先保留证据和回滚点

先记录 df -hTdf -i、异常目录清单、相关服务状态和最近日志。只清理能明确归属、可再生成且不在业务保留期内的缓存或临时文件;日志应通过应用轮转策略处理,数据库、队列、上传目录和用户数据不能按“文件最老”盲删。云主机或容器环境建议先做快照或备份,再执行小批量清理。

复核要看“能否创建”和“业务是否恢复”

清理后重新运行两类检查:

df -hT
df -i
sudo -u <service-user> sh -c 'f=$(mktemp /path/to/app-tmp/check.XXXXXX) && printf ok > "$f" && rm -f "$f"'
systemctl status <service> --no-pager

测试文件必须放在应用真实使用的挂载点,并使用服务账号验证权限。若 inode 很快再次增长,应回到创建者、生命周期和轮转策略,而不是持续扩大文件系统。

常见误区

  • 只扩容数据盘,不处理每 inode 一个文件的设计问题。
  • 对整个 /tmp、容器目录或上传目录执行递归删除。
  • 把“删除后空间未释放”误判为缓存,忽略进程仍持有句柄。
  • 在生产高峰期运行无边界的全盘 find,进一步放大 I/O。

结论

VPS写入失败的第一步是同时查看数据块和 inode,再按目录、进程和挂载点缩小范围。只有确认文件可安全再生成、保留要求已满足并具备回滚点后,才进行小批量清理;最终用服务账号在真实路径写入测试,才能证明故障真正恢复。

常见问题(FAQ)

df -h还有空间,为什么VPS仍提示磁盘不足?
文件系统可能先耗尽inode。df -h统计数据块,df -i统计可创建文件的inode数量;大量小文件会让前者有余量而后者接近100%。
inode耗尽可以直接删除/var下的文件吗?
不应直接递归删除。先确认文件归属、保留期限和是否可再生成,优先按应用的缓存、日志轮转或队列清理策略小批量处理。
删除日志后df -h没有变化怎么办?
用lsof +L1检查已删除但仍被进程打开的文件,再按服务文档优雅重载或重启以释放文件句柄。
怎样确认应用真的恢复了写入?
在真实挂载点用应用服务账号创建并删除临时文件,同时检查服务状态、错误日志和df -h/df -i的变化。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600

VPS磁盘满了最常见的表现:网站打不开(MySQL写不进去)、Docker容器启动失败(没空间写日志)、SSH登录巨慢。本文用du和ncdu两个命令找到谁在吃空间,再针对Docker日志、系统日志和旧备份三类大户下手清理。 第一步:确认磁盘