du统计可见文件实际磁盘占用,df读取文件系统超级块显示整体空间;差异常导致“磁盘满但du总和小”,主因是已删未释放文件、日志堆积或容器残留。

Linux系统中,du(disk usage)和df(disk free)是两个最常用、最基础的磁盘空间分析命令,但它们作用不同、统计逻辑不同,常被误用或混淆。当发现磁盘“明明没存多少文件却显示已满”,或“删除大文件后空间未释放”,往往就和这两个命令的差异有关。
df 显示的是文件系统级别的可用空间
df读取的是文件系统超级块(superblock)中的元数据,反映的是整个挂载点(如 /、/home)的总容量、已用、可用空间,单位默认为KB。它不关心具体有哪些文件,只看底层块设备的分配状态。
- 运行
df -h可以直观看到各挂载点的使用率,重点关注 Use% 列是否超阈值(如 ≥90%) - 注意 Available 不等于 Used + Avail = Size:ext4等文件系统会为 root 预留 5% 空间(可通过
tune2fs -l /dev/sdXn | grep "Reserved block count"查看),普通用户看不到这部分,df 却计入了“可用”统计 - 若 df 显示已满,但 du 扫描目录总和远小于此,常见原因是:已删除但进程仍在占用的文件(lsof + deleted)、日志轮转未清理、或容器/虚拟机镜像残留
du 统计的是目录树中实际可见文件的磁盘占用
du 逐个遍历指定路径下的文件与子目录,累加其 实际占用的磁盘块数(非文件大小,考虑稀疏文件、硬链接、块对齐等)。它反映的是“当前能看见的、可遍历到的数据量”。
- 常用组合:
du -sh /var/* | sort -hr | head -10快速定位 /var 下最大的10个子目录 - 避免权限干扰:加
2>/dev/null屏蔽 “Permission denied” 报错,否则可能漏掉关键路径(如 /root、/proc) - 注意硬链接:同一 inode 多次出现时,du 默认只计算一次;若需按“每个路径独立计数”,加
--apparent-size(但该值≠真实磁盘占用)
du 和 df 结果不一致?先排查这三类典型异常
当 df -h 显示根分区 98% 已用,而 du -sh /* 2>/dev/null | sort -hr 总和仅 20GB,说明有“看不见”的空间消耗。优先检查:
-
已删除但未释放的文件:执行
lsof +L1或lsof | grep deleted,找到仍在打开状态的已删文件,重启对应进程或手动清空(如echo > /proc/PID/fd/FD_NUM) -
日志或临时文件堆积:检查
/var/log/journal(systemd-journald 日志)、/var/log/audit/、/tmp、/var/tmp,用journalctl --disk-usage查看 journal 占用 -
容器或快照残留:Docker 用户运行
docker system df和docker system prune -a;LVM 用户检查lvs是否存在未删除的 snapshot;Kubernetes 节点注意/var/lib/kubelet/pods中 orphaned volumes
日常监控建议:简单有效,避免救火式运维
不要等磁盘爆满才查。把基础检查变成自动化习惯:
- 每天定时执行:
df -h | awk '$5+0 > 90 {print $0}',对使用率>90% 的挂载点告警 - 每周扫描大目录:
du -sh /var/* /home/* 2>/dev/null | awk '$1 ~ /[0-9]+[G]/ {print}',关注 GB 级别以上的异常增长 - 关键服务日志目录(如 /var/log/nginx、/var/log/mysql)配置 logrotate,并验证
logrotate -d /etc/logrotate.d/nginx模拟是否生效 - 在 /etc/fstab 中为重要分区启用
noatime和discard(SSD),减少无谓IO,间接延缓碎片与空间管理开销










