Linux 新手:df 和 du 查出来的磁盘用量为什么不一样

举报
yd_293738966 发表于 2026/10/27 09:54:33 2026/10/27
【摘要】 df 看的是文件系统,du 算的是文件,两者统计口径本来就不一样。本文用新手能懂的方式讲清已删除未释放、稀疏文件、块对齐、硬链接、挂载点遮挡和保留块等六个常见原因,并给出磁盘满了的排查顺序。

刚接触 Linux 时,很多人都会遇到一个让人困惑的现象:用 df 看磁盘快满了,用 du 算一圈却发现文件加起来并没有那么大;或者反过来,du 算出来的结果比 df 大。到底哪一个在说谎?其实两个命令都没有错,只是它们统计的东西根本不一样。

先说结论:df 和 du 看的不是同一本账

  • df 看的是文件系统:整个分区一共多大、用了多少、还剩多少。
  • du 看的是文件:把指定目录下的文件一个一个加起来,看它们占了多少空间。

一个是从文件系统的角度做减法,一个是从文件的角度做加法。口径不同,结果自然不同。理解这一点,后面所有的差异就都好解释了。

常用命令先对齐

df -h
df -h /data
du -sh /data
du -h --max-depth=1 /data | sort -hr

注意两点:第一,df 不加路径时列出所有挂载点,要看清楚是哪一个分区满了;第二,du 不加 -h 时默认单位是 KB,读数容易看错,最好养成加 -h 的习惯。

原因一:文件删了,进程还占着

这是线上最常见的原因。文件被 rm 删除后,如果还有进程打开着它,文件系统不会立刻回收空间。df 仍然认为这部分空间被占用,因为文件系统层面它还没有释放;但 du 遍历目录时已经看不到这个文件了,自然不会把它算进去。

于是就会出现:df 显示已用很高,du 加起来却偏小。

排查方法:

lsof | grep deleted

找到占用已删除文件的进程后,重启进程或让它关闭文件句柄,空间通常就会释放。不要只盯着目录大小反复删除文件,那解决不了这类问题。

原因二:稀疏文件和块分配方式不同

du 默认统计的是文件实际占用的磁盘块,而不是文件的逻辑大小。一个逻辑上很大的稀疏文件,中间有很多空洞,实际可能只占很小的磁盘空间,这时 du 的结果会比文件大小小。

反过来,一个只有几个字节的小文件,也至少要占一个数据块,比如 4KB。目录里有成千上万个小文件时,du 按块统计的结果就会明显大于文件内容的字节数之和。

可以用 ls -s 和 du 对比观察:

ls -lh 文件名
du -h 文件名
du --apparent-size -h 文件名

–apparent-size 看到的是表观大小,不按块算。对比这两个数字,就能直观理解块分配带来的差异。

原因三:硬链接会被重复计算或只算一次

同一个 inode 可以有多个硬链接,分布在不同目录下。du 在遍历时一般只对同一个 inode 计算一次,而如果分开统计不同目录,就可能重复计算。反过来,只看某一个目录时,也可能因为硬链接的存在而低估或高估实际占用。

所以,du 的结果在有大量硬链接的目录里,只能作为参考,不能当作精确的账本。

原因四:挂载点和子目录遮住了真实文件

这也是新手容易忽略的一点。如果一个目录本身原来有文件,后来又在它上面挂载了另一个分区,那么原来目录里的文件就被挂载点遮住了。

du 遍历挂载点时看到的是新分区里的文件,而 df 看的可能是不同的文件系统。更常见的是:根分区满了,但 du 统计时跳过了某些挂载点,或者把别的分区也算了进来,导致口径错位。

排查时先用 df -h 确认满的是哪一个挂载点,再用 du 统计对应的挂载点,而不是笼统地统计根目录。

df -h
mount | grep 需要排查的挂载点

原因五:保留块、元数据和文件系统开销

ext4 等文件系统会默认保留一部分空间给 root 用户使用,防止普通用户把磁盘写满导致系统无法运行。这部分空间在 df 的已用或可用里会体现出来,但 du 统计普通文件时不会把它算进去。

另外,inode、目录项、日志等文件系统自身的开销,也不会体现在某个目录的文件大小之和里。分区越大、文件越多,这种系统性差异就越明显。

原因六:du 默认不跨文件系统,参数不同结果不同

du 默认不会跨越文件系统边界,除非加上 -x 之外的参数组合;而如果手动指定了多个目录,或者统计路径里包含了其他挂载点,结果也会变化。还有,du 的单位换算、是否跟随符号链接,都会影响最终数字。

所以,两个人用不同的 du 参数算同一个目录,得到不同结果是很正常的。对比之前,先把命令和路径对齐。

遇到磁盘满了,推荐的排查顺序

  1. 先用 df -h 定位:到底是哪个分区满了,不要凭感觉清理。
  2. 再用 du -h --max-depth=1 从该挂载点逐层往下找,定位最大的子目录。
  3. 如果 du 加起来明显小于 df,先查已删除但未释放的文件:lsof | grep deleted。
  4. 再看是否有大日志、备份、缓存、容器镜像或旧的安装包在持续增长。
  5. 清理前先确认文件是否还在被使用,重要的日志先压缩或归档,不要直接删除正在写入的文件。
  6. 清理完成后,再用 df -h 复查,确认空间真正释放。

一张表记住区别

对比项 df du
统计对象 文件系统 目录下的文件
数据来源 文件系统元数据 遍历文件并累加
适合场景 判断哪个分区满了 定位哪个目录最大
常见偏差 已删除未释放、保留块 稀疏文件、块对齐、硬链接

写给新手的一句话

df 告诉你磁盘整体的健康状况,du 告诉你空间花在了哪些目录上。两者不一致时,先不要怀疑命令错了,先问一句:统计口径一样吗?有没有被删除却未释放的文件?有没有挂载点遮挡?有没有小文件和稀疏文件的影响?

把这个排查思路走一遍,大多数 df 和 du 对不上的问题,都能找到合理解释,也能避免误删重要文件。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。