跳到主要内容
约 6 分钟5 张卡

磁盘与文件系统排查

文件系统通过目录项、inode 和数据块组织文件。本文负责磁盘容量、文件删除与缓存写回。

1. 面试核心​

先记住这几条,再读正文

2. inode 与文件系统结构​

对象保存内容
目录项文件名与 inode 号的对应关系
inode类型、权限、属主、大小、时间和数据位置
数据块文件内容

ext4 还包含超级块、位图和 inode 表。路径查找逐级解析目录项,找到目标 inode。目录及 inode 缓存能减少实际磁盘读取。

硬链接是指向同一 inode 的不同名称。删除一个名称会减少链接数。剩余名称仍可访问该文件。

ext4 在创建文件系统时配置 inode 容量。扩展文件系统可增加块组和 inode。大量小文件仍可先耗尽 inode。其他文件系统的 inode 分配方式应分别确认。

ls -i 查看 inode 号,stat file 查看元数据。同一文件系统内的普通 rename 主要改变目录项。跨文件系统移动需要复制再删除。

3. 磁盘容量排查​

  1. 用 df -h 与 df -i 确认挂载点和耗尽资源。
  2. 用 du 逐层定位目录,并注意访问权限。
  3. 用 find 查找大文件或大量小文件的来源。
  4. 核对打开文件、业务用途与保留策略后处理。
  5. 通过轮转、配额和增长告警控制后续写入。
du -xh --max-depth=1 /data | sort -rh | head
find /data -xdev -type f -size +1G -exec ls -lh {} \;
du --inodes -x --max-depth=1 /data | sort -nr | head

这里使用 GNU du。前两条定位空间大户,第三条比较 inode 数量。-x 和 -xdev 将范围限制在同一文件系统。

正在写入的日志优先通过应用轮转并重新打开。旧文件关闭后,再按策略清理。截断会丢弃已有内容,还会保留原文件偏移。非追加写入沿用原偏移。若该偏移超过新文件长度,后续写入会产生空洞。因此,截断只适合已确认写入语义的场景。

4. 空间占用与 df、du 差异​

现象核对方向
删除后 df 用量不降lsof +L1 查已删除但仍打开的文件
df 高、du 低打开文件、挂载遮挡、元数据和访问权限
文件可见大小很大、du 很小稀疏文件
空间未满却写入失败inode、配额、预留块、只读挂载与 I/O 错误

unlink 删除目录项。最后一个硬链接消失后,打开引用仍会延长文件生命周期。内存映射也可持有文件引用。释放最后引用后,文件系统才可回收空间。

lsof +L1 用于寻找链接数小于 1 的打开文件。找到持有者后,可通知应用重新打开日志。重启也能关闭引用,但需评估业务影响。

挂载会遮住目录中原有内容。维护时可用额外的非递归绑定视图检查底层目录。直接卸载业务挂载点会中断访问,应按维护方案操作。

5. buffer 与 cache​

页缓存保存文件内容。缓冲写入先修改缓存页,再由写回流程落盘。块设备缓存则用于块设备访问。

procps 的 free 将多类缓存汇总为 buff/cache。它包含 buffers、页缓存与可回收 slab。该值并非全部都能立即回收。

available 估算在不发生交换时还能提供多少内存。脏页需写回,部分 slab 也无法即时释放。因此,还需结合交换速率和内存压力判断。

清理缓存会让后续读取重新访问存储。性能排查应先确认压力来源。手工 drop_caches 只适合明确的测试需求。

6. 稀疏文件与持久化​

稀疏文件的逻辑大小可大于已分配空间。未分配区间读取为零。ls -l 显示逻辑大小,du 默认统计已分配块。du --apparent-size 可比较逻辑大小。

write() 成功说明数据已被系统接受。缓冲 I/O 下,数据还会等待写回。fsync(fd) 将文件数据与元数据同步到存储设备。调用还需检查返回值和设备错误。

新建文件或 rename 后,目录项也需要持久化。应用应对相关目录描述符执行 fsync。文件内容同步与目录项同步分别承担不同任务。fdatasync 只同步数据及读取数据所必需的元数据。

7 · 面试题卡片​

本页题目与参考回答

7.1 什么是 inode?文件系统由哪些部分组成?​

考察重点

  • 目录项、inode、数据块的分工;文件名不在 inode 中。
  • inode 数量有限,以及由此引出的 inode 耗尽和硬链接。

相关内容:inode 与文件系统结构。

参考回答

inode 保存文件类型、权限、属主和数据位置等元数据。

文件名由目录项保存。路径查找通过目录项找到 inode,再访问数据。

硬链接是同一 inode 的不同名称。ext4 的 inode 容量受格式化和后续扩容影响。大量小文件会先耗尽 inode。排查时用 df -i 区分 inode 与块空间。

7.2 磁盘使用率很高甚至打满了,你怎样排查和处理?​

考察重点

  • 区分空间满和 inode 满。
  • 用 du、find 逐层定位;安全地清理正在写入的文件;事后的预防。

相关内容:磁盘容量排查。

参考回答

先区分块空间耗尽、inode 耗尽和其他写入错误。

df -h 与 df -i 确认挂载点。du -x 逐层查目录,find 查大文件。GNU du 的 --inodes 可比较 inode 使用量。

清理前确认业务用途、打开引用与保留策略。日志优先轮转并让应用重新打开。截断需确认内容可丢弃及追加写入语义。之后补充轮转、配额、容量与增长告警。

7.3 删除了大文件但空间没有释放,或者 du 找不到大文件但 df 显示快满了,可能是什么原因?​

考察重点

  • 删除操作只减少链接计数,进程打开的文件不会释放。
  • df 与 du 的统计方式不同;挂载点遮挡和隐藏文件。

相关内容:空间占用与 df、du 差异、inode 与文件系统结构。

参考回答

已删除但仍被打开的文件,是常见原因。

unlink 移除目录项,打开引用仍保留文件。du 遍历不到该名称,df 仍统计已分配空间。

先用 lsof +L1 找持有进程。让应用关闭旧日志并重新打开,才能释放引用。还要核对挂载遮挡、权限和文件系统元数据。稀疏文件则会让逻辑大小大于实际占用。

7.4 buffer 和 cache 有什么区别?​

考察重点

  • 页缓存缓存文件内容,buffer 缓存块设备数据。
  • 理解缓存回收条件与 available 的含义。

相关内容:buffer 与 cache。

参考回答

页缓存保存文件内容,buffer 对应块设备缓存。

free 的 buff/cache 还包含可回收 slab。脏页需要写回,缓存也有暂时无法回收的部分。

判断内存压力应看 available、交换速率和压力指标。available 估算无交换时可供新应用使用的内存。单看 free 很低,无法判断内存已经不足。

7.5 为什么 ls 与 du 的大小不同?write 成功后文件就能抗断电吗?​

考察重点:稀疏文件、缓存写入与目录同步。

相关内容:稀疏文件与持久化。

参考回答

ls 显示逻辑大小,du 默认统计已分配块。

稀疏文件的空洞会造成两者差异。write 成功后,缓冲数据仍可处于页缓存。持久化需执行 fsync 并检查返回值。新建或重命名还需同步相关目录。

8. 参考资料​