凌晨收到告警后,运维人员登录VPS检查磁盘,发现根分区明明还剩几十GB空间,应用却不断报“无法创建文件”。新建日志、写入缓存、生成临时文件都可能失败,而df又看不出异常。这类故障的核心,往往不是磁盘容量,而是文件系统inode配额已经耗尽,也可能是进程文件句柄达到上限。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:sixtynet(全球云服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
空间、inode与句柄:三种资源不能混为一谈
磁盘容量回答的是“还能存多少字节”。普通ext4文件系统会预先为每个文件分配一个inode,记录文件类型、权限、所有者、时间戳和数据块位置。inode数量在格式化时确定,也可以通过配额机制单独限制。假设分区有100GB空间,若系统只配置了10万个inode,平均每个inode对应约1MB存储空间;大量几KB的小文件会迅速吃掉数量配额,但不会明显增加已用容量,于是出现空间未满却无法创建文件的反差。
创建文件通常至少需要目录项、数据块和inode;硬链接会增加目录项,目录本身也占用inode。临时文件、缓存碎片、频繁轮转的日志、未清理的会话文件,都可能成为小文件堆积的来源。需要注意,目录项缓存(dentry cache)属于内核内存中的目录查找缓存,作用是加速路径解析,它不是inode配额。缓存可以回收,也不能解释df中的IBlocks已满,但内存紧张时会表现为系统响应缓慢或缓存被频繁回收。

先判断失败发生在哪一层
第一步看报错语义。应用或系统返回“No space left on device”,通常指向数据块或inode耗尽;返回“Too many open files”,更像是进程的文件句柄达到限制;出现“File exists”或目录操作异常,则应检查权限、残留文件、挂载状态和服务自身限制。句柄耗尽不是磁盘inode耗尽,前者受ulimit、systemd限制和服务配置影响,后者属于文件系统层面的对象数量限制。
第二步把df、df -i和stat放在一起看。df -h展示块设备容量,df -i展示各挂载点的inode总数、已用数和剩余数。若IUsed接近Icount,即使磁盘仅使用20%,也应优先处理inode。相反,如果inode充足而报错为EMFILE,可执行ulimit -n查看当前shell限制,再检查进程的打开文件数;此时盲目清理小文件,方向通常不对。
第三步定位消耗者,而不是直接删除未知目录。使用du --inodes -x /逐层统计inode占用,再用find配合size、mtime和type筛选大量小文件;lsof可检查异常进程是否持有大量已删除文件。生产环境中应先确认路径归属和保留周期,避免误删正在写入的日志、数据库文件或运行中的任务。ServLlama这类面板工具可用于汇总主机资源与异常项,但最终仍要回到命令行核对真实文件系统数据。

目录项缓存与真实空间占用
ext4 的目录并非只保存文件名。目录数据、目录索引(如 htree)、扩展属性都可能占用数据块,所以会出现 df -h 尚有空间,du 却逼近满载,或删除文件后空间没有立即归还的现象。内核中的 dentry/inode 缓存主要消耗内存,用于加速路径查找,并不等于磁盘 inode;可用 free、slabtop 或 /proc/slabinfo 观察,不要把缓存驻留误判为 inode 泄漏。文件系统 inode 总量则可通过 tune2fs -l /dev/xxx 查看 Inode count 与 Free inodes,并结合 df -i 判断是否真的耗尽。
创建文件失败也不只由 inode 引起。返回 ENOSPC 可能是 inode、项目配额、目录扩容、数据块或保留块耗尽;EDQUOT 通常指向用户或项目配额,EACCES 更常见于目录权限,EROFS 表示只读挂载。若 inode 已耗尽,单纯清理大文件通常无效,应先定位小文件密集目录和异常 UID/GID 文件。ext4 的 pquota、repquota 可核对项目配额,find 可按类型、数量、时间和所有者统计,避免直接遍历过大的单一目录。

小文件治理要先量化,再分级处置
治理时先设置容量与 inode 双重阈值,并保留业务写入余量。可用 find /data -xdev -type f -printf '%u %g %s %p\n' 导出样本,再按目录汇总文件数与逻辑大小;注意 du --apparent-size 只统计文件内容,不等于实际分配块,稀疏文件尤其容易失真。临时文件、缓存碎片和日志轮转产物应设置保留周期,历史对象优先迁移到对象存储或归档盘。必须保留的文件可合并、压缩或重新打包,但不建议在业务高峰直接改权限、截断文件或删除目录 inode。对 NFS、FUSE、容器挂载和数据库数据目录,要先确认后端配额及删除语义,避免本地 df 正常而远端已满。
最终检查清单:确认设备与挂载点;执行 df -h、df -i、du -x 对比容量和 inode;用 tune2fs -l 核对文件系统总量,用 repquota 检查用户及项目配额;按目录统计小文件数量、归属者和增长速率;核对保留块、目录索引、NFS 或容器后端限制;先备份并灰度清理,再持续监控 inode 使用率与创建文件错误码。


喜欢
顶
难过
囧
围观
无聊





