Linux中df与du结果不一致的常见原因有四:一是被删除但仍在使用的文件(lsof+deleted);二是ext文件系统保留块(默认5%);三是挂载覆盖或bind mount导致路径指向不同文件系统;四是df与du默认单位进制差异(1024 vs 1000),需统一单位比对。

Linux 中 df 显示磁盘空间“异常”——比如已用 100%,但 du 统计总和远小于此,或删除大文件后空间不释放——通常不是命令出错,而是有特定原因可查。
检查是否有被删除但未释放的文件(lsof + deleted)
进程仍在使用已被 rm 删除的文件时,磁盘空间不会立即释放,df 仍会计入,但 du 找不到该文件(因目录项已删)。这是最常见原因。
执行以下命令查看:
lsof +L1 /path/to/filesystem # 查看指定挂载点下被删除但仍被打开的文件
或更通用的方式:
lsof | grep 'deleted' | grep '/mnt/your-mount' # 替换为实际挂载路径
若发现结果,说明对应进程占用了已删文件的空间。解决方法是重启该进程,或向其发送信号(如 kill -HUP)促使其重新打开日志/文件;若为日志服务(如 nginx、rsyslog),也可用 logrotate 或手动 kill -USR1 触发重载。
确认是否启用了 reserved blocks(根分区常见)
ext 系列文件系统默认为 root 用户保留 5% 的空间(防止系统完全写满崩溃),df 显示的 “Available” 已扣除这部分,但 “Used” 包含它。普通用户看不到这 5%,所以可能误判为“空间没释放”。
查看保留比例:
tune2fs -l /dev/sdXN | grep 'Reserved block count\|Block count'
计算保留空间大小:Reserved block count × Block size。若需临时调整(不推荐生产环境随意改):
tune2fs -m 1 /dev/sdXN # 设为 1%,仅限非根分区或充分评估后操作
排查挂载覆盖(mount overlay)或 bind mount 干扰
如果在已有目录上执行了新挂载(如 mount /dev/sdb1 /var/log),原 /var/log 下的文件会被隐藏,du /var/log 统计的是新文件系统内容,而 df /var/log 显示的是新挂载设备的空间——两者自然不一致。
检查挂载层级:
findmnt /var/log # 查看该路径实际挂载源
mount | grep " /var/log " # 注意空格,避免匹配子串
若发现非预期挂载,确认是否应卸载或调整挂载点。另外,bind mount(如 mount --bind /data/logs /var/log)也会导致类似现象,需结合 findmnt -D 查看完整挂载树。
注意 df 默认单位与 du 单位不一致(易被忽略)
df 默认以 1K 块(1024 字节)为单位显示,而 du -sh 使用人类可读单位(如 K/M/G),且按 1000 进制或 1024 进制取决于系统和选项(GNU coreutils 默认 1024)。直接对比数值会偏差。
统一单位再比对:
df -B1 / # 按字节输出,精确可比du -sb /var/log # 同样按字节统计子目录- 或都用
-h但理解其进制差异:1G 在df中 ≈ 1024×1024×1024 字节,在du -h中也基本一致,但小数位四舍五入可能导致表观差异
真正的问题往往不在单位,但在排查初期排除此干扰能少走弯路。










