题干与适用场景
字节使用率正常不等于文件系统还能创建文件。ext4 等文件系统同时管理数据块和 inode;大量小文件、缓存碎片、邮件队列或容器层可能先耗尽 inode。题目要求在服务仍运行时定位根因,不能直接删除未知目录或重启掩盖证据。
公开 Linux/DevOps 面试资料常把“磁盘满”作为排障场景;df 文档和 Linux 内核 ext4 文档提供了块、inode、目录项之间的事实边界,因此回答应从可观测证据推导行动,而不是背诵清理命令。
面试官考察点
- 能否区分字节块、inode、用户配额和容器可写层四种容量边界。
- 能否先确认受影响的挂载点、错误时间和写入路径,再执行低风险定位。
- 能否定位小文件热点、隐藏挂载、日志轮转缺口,以及删除后仍被进程持有的文件。
- 能否选择可回滚、可审计的恢复动作,避免
rm -rf和盲目重启。 - 能否把 inode 使用率、文件数增长和目录热点纳入容量预算与告警。
回答前需要澄清的问题
- 报错进程写入哪个路径和挂载点?宿主机、容器、临时目录是否相同?
df -h与df -i的结果分别是什么?是否存在用户或项目配额?- 失败是创建新文件、扩展已有文件,还是写入 overlay、tmpfs 或网络文件系统?
- 是否有正在进行的发布、日志轮转、备份或批处理?删除动作是否受合规保留约束?
- 服务能否短暂降载,是否有健康检查和回滚窗口?
30 秒回答框架
“我先固定错误进程、挂载点和时间窗,同时比较 df -h 与 df -i。若 inode 接近 100%,我会按目录和文件数量定位热点,检查容器可写层、日志轮转和配额;若 inode 正常,再查块空间、保留块和删除但仍打开的文件。恢复优先选择轮转、压缩、清理已确认的临时数据或扩容,并保留证据。最后建立 inode、字节、目录文件数和增长率告警,避免只监控百分比磁盘空间。”
分步骤深入解答
第一步:确认故障边界
保存应用日志、内核日志、失败路径和挂载信息。不要一开始就删除文件;先确认是单个服务、单个容器,还是整台主机都无法创建文件。相同错误文案可能来自 inode、块、配额或只读文件系统。
第二步:并列检查块和 inode
df -hT /
df -iT /
findmnt -T /var/lib/appdf -h 观察数据块,df -i 观察 inode。两者都要按受影响路径对应的挂载点读取。若 inode 使用率接近 100% 而字节仍有余量,优先走小文件定位;若 inode 正常,继续检查块空间、配额、只读状态和容器限制。
第三步:按数量定位目录热点
先统计目录项数量而不是读取全部文件内容,避免对线上盘造成额外 I/O。可以对候选目录分层计数,再只深入增长最快的分支。find 的遍历应限定路径、排除其他挂载,并在高峰期设置资源预算。目录项映射到 inode,目录里有大量小文件时,字节占用可以不高但 inode 会耗尽。
第四步:区分真实文件与挂载边界
容器 overlay、bind mount、tmpfs 和日志卷可能让宿主机看到的路径与进程实际写入层不同。用进程工作目录、容器配置和 findmnt -T 交叉确认。不要在宿主机删除容器层文件来“修复”容器;应通过容器运行时、卷策略或应用清理路径执行。
第五步:检查轮转、缓存和删除后仍打开的文件
日志轮转可能只重命名而未让进程重新打开,缓存可能无限产生短文件。lsof +L1 可以找出链接数为零但仍被进程持有的文件;释放空间通常需要让拥有者按安全方式关闭或重新打开文件。重启不是默认动作,因为它会丢失现场,也可能让瞬时写入再次触发。
第六步:选择恢复动作
按风险排序:先停止产生临时文件的非关键任务,再轮转或压缩已确认的日志,清理有保留策略的缓存,最后扩容或迁移。每一步记录路径、大小、文件数、负责人和回滚方式。删除前验证文件不是当前配置、队列、数据库或审计证据,并在低峰执行。
第七步:验证恢复和副作用
恢复后再次运行 df -hT、df -iT,执行一次真实的临时文件创建、日志写入和关键请求。确认 inode 使用率下降、错误率恢复、延迟没有因清理或压缩恶化。对容器还要验证重建后文件数不会立即回升。
第八步:建立长期防线
监控块与 inode 使用率、每个挂载点文件数、目录增长率、日志轮转延迟、删除后打开文件数和容器层大小。阈值要配合增长速度和处置时间,而不是只设一个 90%。把清理、扩容、轮转恢复和验证步骤写入可执行运行手册,并定期演练。
设计取舍与边界
清理与扩容
清理能快速恢复但可能重复发生;扩容提高余量却不修复小文件生成源。先恢复服务,再用增长证据决定是改应用、改轮转、调整文件粒度还是扩容。
统计精度与线上成本
全盘 find 精确但昂贵;目录级计数和采样更适合持续监控。事故中逐步缩小范围,避免在 I/O 紧张时递归读取整个文件系统。
宿主机与容器
宿主机指标不能替代容器卷和 overlay 指标。每个写入层都要有配额、负责人和清理边界;跨层删除可能制造不可预测的镜像或卷问题。
失败演练与演进计划
失败:只看 df -h
字节空间有余量时仍可能 inode 为零。把 df -i 纳入首轮诊断和告警,并按挂载点保存历史。
失败:直接 rm -rf 最大目录
目录可能包含队列、证据或当前写入文件。先确认所有者、保留策略、打开句柄和回滚,再分批清理。
失败:用重启代替恢复
重启可能暂时释放已删除文件,却丢失现场并掩盖生成源。优先让拥有者安全关闭文件并验证再次写入。
常见误区与追问
误区:inode 只与文件大小有关
inode 主要受文件数量和文件系统格式影响;大量零字节或小文件也会耗尽它。
追问:为什么删除文件后空间没回来?
进程仍持有文件描述符时,目录项已删除但数据块和 inode 仍被占用;确认持有者并安全重开文件。
追问:如何区分配额问题?
对照挂载点全局指标与用户、项目、容器配额,并以同一身份在同一路径做受控创建测试。
追问:日志轮转如何验收?
验证轮转后进程打开新文件、旧文件句柄关闭、文件数和 inode 使用率按预算回落,而不是只看到新文件名。
追问:如何防止小文件风暴?
批量合并、按时间分片、限制缓存条目、设置轮转上限,并监控文件创建速率和目录项增长。
追问:什么时候扩容没有帮助?
当 inode 设计上已固定且新盘格式仍提供相同 inode 密度时,单纯增加字节容量不能解决 inode 耗尽;应迁移、重建或改变文件粒度。