60 秒回答模板

Linux 删除文件通常是 unlink,先移除目录项;只有当文件的硬链接数为 0,并且没有进程持有打开的文件描述符时,inode 和数据块才会释放。如果日志文件被删除但进程仍在写它,du 遍历目录看不到这个文件,df 却仍显示文件系统空间被占用。排查时用 lsof +L1 或 lsof | grep deleted 找到持有进程,优先让进程重新打开日志、优雅重启或关闭对应 fd,再确认空间释放。

考点 核心机制与工程取舍
难度 中高频面试题
回答目标 按定义、机制、场景讲清楚

深入解析

01

删除语义

rm 本质上调用 unlink 移除文件名到 inode 的目录项引用。文件名消失后,数据是否释放还取决于硬链接计数和打开文件描述符引用。

02

空间未释放

进程打开文件后,内核通过 fd 继续引用 inode。即使目录项已经删除,进程仍可读写该文件,数据块不能回收,直到最后一个 fd 关闭。

03

df 与 du 差异

du 通过遍历目录项统计可见文件大小,已删除但仍打开的文件没有路径可遍历;df 从文件系统块使用量统计,所以仍能看到空间被占用。

04

排查处理

用 lsof +L1、lsof | grep deleted 或查看 /proc/<pid>/fd 定位持有者。处理优先级是让服务重新打开日志、优雅重启、关闭 fd;不建议盲目 kill 核心进程。

05

预防方案

日志切割应使用 copytruncate 或切割后向进程发送重新打开日志的信号,应用也应支持 logrotate 协作。大文件清理要先确认是否仍被进程持有。

易错点

  • 反复执行 rm 或清目录,却不检查是否有进程持有 deleted 文件。
  • 混淆 df 和 du 的统计口径,认为工具结果矛盾就是文件系统坏了。
  • 直接 kill 进程释放空间,没评估服务影响和优雅重启方式。
  • 日志切割后没有通知进程重新打开日志文件。

面试官追问

为什么 du 看不到但 df 还能看到?

du 只能遍历目录树中的文件,已 unlink 的文件没有目录项;df 看的是文件系统块占用,仍打开的 inode 占用会被统计。

如何安全释放空间?

确认持有进程后,让服务重新打开文件或优雅重启;必要时清空 /proc/<pid>/fd 对应文件描述符,但要谨慎评估进程行为。

日志切割为什么会出现这个问题?

如果切割工具删除或重命名日志后,进程没有重新打开新文件,进程会继续向旧 inode 写入,旧文件路径不可见但空间持续增长。

硬链接会影响释放吗?

会。只有硬链接计数为 0 且没有打开 fd 时才释放数据块,存在其他硬链接时删除一个路径不会释放内容。