最近更新时间:2025-11-24 14:55:46
在 Linux 服务器运维过程中,管理员常通过df -h与du -sh命令查看磁盘空间占用情况,但可能遇到两者统计结果不一致的场景,具体现象如下:
执行df -h命令查看文件系统使用率时,显示/dev/xvdb1分区(挂载目录为/opt)占用约 30G;
进入/opt目录后执行du -sh命令,显示该目录下文件总占用空间仅约 14G,两者数据存在明显差异。
命令 | 核心功能 | 数据来源 | 统计范围 |
| 报告文件系统整体磁盘空间使用情况 | 直接读取文件系统的超级块(Super Block) 元数据 | 仅针对整个分区(如/dev/xvdb1),无法统计单个目录 |
| 估算文件 / 目录的实际磁盘空间占用 | 对目标路径下的每个文件逐个调用fstat系统调用,获取单个文件大小后累加 | 可针对单个文件、目录,支持跨分区统计(需指定路径) |
当用户执行rm命令删除文件时,仅会从文件系统的目录结构中移除该文件的引用,但若此时仍有运行中的进程持有该文件的句柄(File Handle),则文件系统不会真正删除磁盘上的文件数据。
此时会出现以下矛盾:
du命令:因文件已从目录结构中消失,无法遍历到该文件,故不统计其占用空间;
df命令:因超级块未更新 “已使用空间”,仍会将该 “已删除但未释放” 的文件计入分区占用量,导致两者统计结果不一致。
通过lsof(List Open Files)命令可查询系统中所有处于 “已删除(deleted)” 状态但仍被进程占用的文件,终止其进程或重启服务:
lsof | grep deleted执行后若输出大量包含 “deleted” 标识的文件记录(格式示例:process_name PID user fd type device size/off inode path (deleted)),则可确认是此类文件导致df与du统计不一致。
若明确进程无核心业务影响,可直接通过kill命令终止进程,释放文件句柄:
kill -9 {PID}若通过lsof命令查询到大量文件句柄,且无法逐一定位关联进程,可通过重启服务器彻底释放所有进程持有的文件句柄。
服务器重启过程中,会强制终止所有运行中的进程,开机后重新加载文件系统,此时所有 “已删除但未释放” 的文件句柄会被自动释放。
删除大文件(尤其是被服务进程占用的日志文件、临时文件)前,先通过lsof命令确认是否有进程持有该文件句柄,若有则先停止关联服务再删除。
可通过定时任务定期执行lsof | grep deleted命令,监控系统中 “已删除但未释放” 的文件,发现异常及时处理,避免长期占用磁盘空间。
纯净模式
