当前位置:首页 > 文章列表 > 文章 > linux > 磁盘空间没满却无法写入:inode、配额与保留块检查

磁盘空间没满却无法写入:inode、配额与保留块检查

来源:17golang原创 2026-10-07 12:21:19 0浏览 收藏

Linux 报 No space left on device,并不只表示“磁盘字节用完”。创建或扩展文件至少会受到四类限制:文件系统的数据块、可分配 inode、当前用户/组/项目的配额,以及 ext2/3/4 留给特权进程的保留块。只看一眼 df -h 的容量百分比,很容易删错目录或误改文件系统参数。

我处理这类问题时,先固定报错路径和执行身份,再记录四组基线指标。目标不是立刻“释放一点空间”,而是找出哪一个计数先到边界。ENOSPC 表示设备没有可用空间,EDQUOT 表示磁盘配额耗尽;不少应用会把底层错误统一包装成相似文案,所以最终仍要回到文件系统指标。

GNU df 官方文档:https://www.gnu.org/software/coreutils/manual/html_node/df-invocation.html

Linux 内核 ext4 文档:https://www.kernel.org/doc/html/latest/filesystems/ext4/

判断顺序
  • 先用 findmnt -T 确认报错目录究竟落在哪个挂载点和文件系统。
  • df -h 看数据块,df -i 看 inode;两者是独立资源。
  • 两组都有余量时,检查当前用户、组或项目是否碰到配额 hard limit。
  • 只有文件系统是 ext2/3/4 时,才检查特权进程保留块;不要把 XFS、Btrfs 或网络文件系统套进 ext 的处理方式。

先建立基线:确认路径、挂载点和四组指标

一次让我印象很深的故障发生在日志目录:根分区看起来还有空间,应用却无法创建新的轮转文件。最初大家围着最大的日志删文件,后来才发现应用目录是单独挂载,且小文件把 inode 用完了。这个经历之后,我不再从设备名猜挂载点,而是始终让命令围绕真实报错路径执行。

# 把这里改成真正报错的目录,所有检查都围绕同一路径进行。
target_path="/srv/app/data"

# 确认该路径对应的设备、文件系统类型、挂载点和挂载选项。
findmnt -T "$target_path" -o SOURCE,FSTYPE,TARGET,OPTIONS

# 检查数据块总量、已用量、普通进程可用量和使用率。
df -hT -- "$target_path"

# 检查 inode 总数、已用数、可用数和 IUse%。
df -i -- "$target_path"

df 接收路径时,会报告包含该路径的文件系统;-i 则把块使用信息换成 inode 使用信息。GNU 文档把 inode 定义为保存文件所有者、权限、时间戳和磁盘位置等信息的索引节点。对 ext4 来说,inode 表按块组预先组织,因此“还有很多数据块”和“还能不能创建新文件”是两个问题。

基线指标危险证据优先假设
df -h 的 Avail普通进程可用量为 0数据块耗尽,或只剩特权进程保留块
df -i 的 IFree / IUse%IFree 为 0 或 IUse% 为 100%inode 耗尽,常见于海量小文件
quota 的 used / hard块或文件数达到 hard limit用户、组或项目配额阻止继续写入
文件系统类型ext2、ext3 或 ext4继续核对保留块;其他类型走各自工具
目标挂载点的数据块、inode、身份配额和特权保留块四类写入容量关系
图1:写入容量的四维静态结构。目标挂载点同时受数据块与 inode 约束,调用身份还可能受到用户、组或项目配额限制;ext 保留块只对特定特权身份开放。这是结构说明图,不是运行截图。

假设一:inode 用完,字节容量仍然充足

inode 耗尽最符合“空间没满却创建不了新文件”的直觉冲突。一个很大的文件通常只占一个 inode,而百万级缓存碎片、会话文件、邮件队列或未清理的空文件,会快速消耗 inode,却未必占用多少数据块。

# 继续检查同一目标路径,避免把其他分区的 inode 指标当成证据。
target_path="/srv/app/data"
df -i -- "$target_path"

# 只在已确认的挂载点内按目录汇总文件数量,-xdev 避免跨入其他文件系统。
find "$target_path" -xdev -type f -printf '%h\n' \
  | sort \
  | uniq -c \
  | sort -nr \
  | head -n 20

第二段命令可能在文件极多时本身也比较重,应先缩小到业务已知目录,并避开高峰。证据成立时,正确动作通常是按业务保留期清理、归档或合并小文件,调整缓存和轮转策略;不是去删除某个大文件。inode 数量通常在文件系统创建时确定,后续不能把剩余字节简单“转换”为 inode。

复测也必须看两项:删除或归档后,IFree 应增加;应用使用原身份在原目录创建文件应恢复。只看到 df -h 的 Used 降低,不足以证明 inode 问题已经解决。

假设二:当前身份达到配额,文件系统全局仍有余量

配额是另一套独立计数。Linux 配额系统可以对用户、组和项目限制文件系统中的空间与 inode 使用量。hard limit 不能超越;soft limit 可以暂时超过,但过了宽限期会按硬限制处理。于是管理员查看全局 df 时还有余量,应用账号仍可能收到配额错误。

# 以当前登录身份查看用户配额,-s 使用易读单位。
quota -s

# 查看当前用户所属组的组配额;不同发行版可能需要安装 quota 工具包。
quota -g -s

# 管理员汇总本机已启用文件系统的用户与组配额,命令仅做报告。
sudo repquota -a

检查时要同时看空间块和文件数限制。有些账号没有碰到字节 hard limit,却已经达到 inode hard limit;有些容器或工作目录使用项目配额,普通 quota -s 看不到项目维度,需要按文件系统类型使用管理工具核对项目 ID。

如果配额正是组织的隔离策略,不要通过换成 root 写入来“绕过去”。合理修复是清理该身份拥有的过期数据,或由管理员根据容量预算调整 hard limit。调整后用同一个应用账号、同一个目录复测,避免管理员身份成功而业务进程仍失败。

假设三:ext 保留块让普通进程先看到 Avail 为零

ext2、ext3 和 ext4 可以保留一部分文件系统块,只允许特权进程分配。tune2fs 手册说明,这样做一方面降低文件系统严重填满时的碎片风险,另一方面让 syslogd 等系统守护进程在普通进程被禁止写入后仍能继续工作;默认保留比例通常是 5%。

这个机制只应在 findmnt 已确认文件系统为 ext2/3/4 后检查。下面命令只读取超级块,不修改参数:

# 从真实报错路径解析底层设备和文件系统类型。
target_path="/srv/app/data"
filesystem_type="$(findmnt -n -o FSTYPE -T "$target_path")"
source_device="$(findmnt -n -o SOURCE -T "$target_path")"

# 只有 ext2/3/4 才使用 tune2fs 读取保留块;其他类型必须改用对应工具。
case "$filesystem_type" in
  ext2|ext3|ext4)
    sudo tune2fs -l "$source_device" \
      | grep -E 'Block count|Free blocks|Reserved block count|Reserved block percentage'
    ;;
  *)
    printf '文件系统 %s 不适用 tune2fs 保留块检查\n' "$filesystem_type"
    ;;
esac

如果 df -h 显示普通进程的 Avail 已接近零,而超级块仍有明显的 Reserved block count,就能解释为什么 root 还能写、业务账号却失败。但这不是“隐藏的免费空间”。直接把保留比例调到 0 会削弱系统在满盘时保留日志、远程登录和清理能力,尤其不适合根文件系统。

对于超大、纯数据用途且有独立监控和应急预案的 ext 文件系统,可以在容量评审后评估较低比例;真正的长期方案仍是扩容、限流和清理策略。本文只检查,不给出一条可盲目复制的修改命令。

df 块指标、df inode 指标、quota 限制、findmnt 类型和 tune2fs 保留块的静态证据矩阵
图2:只读诊断证据矩阵。df -h、df -i、quota、findmnt 与 tune2fs 分别回答不同问题;要让证据指向同一目标挂载点和同一调用身份。这是静态说明图,不是终端截图。

按证据改动,而不是按错误文案猜原因

证据组合结论优先处置不建议
Avail 为 0,inode 有余量数据块或保留块边界先清理/扩容,再按文件系统类型检查保留策略只删大量空文件
IFree 为 0,块有余量inode 耗尽归档小文件,修正缓存与轮转只删除一个大文件
块和 inode 都有余量,quota 达 hard身份配额限制清理该身份数据或审批调整配额改用 root 绕过
ext 文件系统、普通 Avail 为 0、仍有保留块只剩特权保留容量恢复安全余量,评估专用数据盘比例在根分区盲目设为 0

如果四组指标都没有触边,就要扩大排查范围:挂载点是否变成只读、应用是否写到另一个 namespace、删除但仍被进程打开的文件是否占用块、底层存储或网络文件系统是否延迟分配失败。它们同样可能造成写入失败,但不能用 inode、配额或保留块的结论硬解释。

复测方法:同一路径、同一身份、同一类型操作

修复后,我会保留变更前后的四项数值,而不是只看应用重启后“暂时不报错”。复测应满足:

  1. findmnt -T 仍指向预期挂载点,没有把测试写到别的文件系统。
  2. df -h 的 Avail 留出运维安全余量,不是刚从 0 变成极小值。
  3. df -i 的 IFree 明显恢复,并且增长速度受清理或轮转策略约束。
  4. 应用身份的空间和文件数配额都低于 hard limit,必要时也核对项目配额。
  5. 使用业务进程的同一用户,在原目录完成真实的创建、追加和删除,而不是只让 root 执行 touch。

指标驱动的价值在这里很直接:inode 问题修复后,IFree 会变化;配额问题修复后,used 与 hard 之间会重新出现余量;保留块问题则会体现为普通进程可用量与特权可用范围的差异。每个改动都应有对应数字,而不是依赖“删了一些东西”的感觉。

常见问题

df -h 没到 100%,为什么仍然写不进去?

先看 Avail 而不是只看 Use%。还要核对 inode 和配额。ext 文件系统只剩保留块时,普通进程可能已经没有可分配块,而特权进程仍保有应急空间。

df -i 的 IUse% 为 100% 应该删大文件吗?

通常优先找海量小文件。大文件和小文件都需要 inode,但一个大文件通常只占一个 inode;删除单个大文件会释放数据块,却未必解决 inode 耗尽。

root 能写、应用账号不能写就一定是保留块吗?

不一定。用户、组或项目配额以及目录权限也会造成身份差异。先看 errno、quota 报告和文件系统类型,再判断是否是 ext 保留块。

可以直接把 ext4 保留块比例改成 0 吗?

不建议把它当成通用修复。根文件系统尤其需要保留应急写入能力。专用大数据盘是否降低比例,应结合容量、碎片风险、监控和故障恢复方案单独评审。

“磁盘空间没满却无法写入”不是一个单指标问题。数据块回答还能写多少字节,inode 回答还能创建多少文件对象,配额回答当前身份还能使用多少资源,保留块回答普通进程与特权进程的可用边界。把这四类证据放在同一个目标路径上,排障才会从猜测变成可复查的判断。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
通过 replace 临时联调本地依赖并在提交前移除替换通过 replace 临时联调本地依赖并在提交前移除替换
上一篇
通过 replace 临时联调本地依赖并在提交前移除替换
模块路径改名后旧依赖如何平滑迁移而不制造双份包
下一篇
模块路径改名后旧依赖如何平滑迁移而不制造双份包
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    363次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    419次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    433次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    386次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    213次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码