df命令与du命令查询结果不一致

1.前言

今早服务器有告警短信,提示主机磁盘空间已满,上机之后使用df命令查看磁盘确实满了,但当我用du命令想查看具体是哪个文件夹过大的时候发现根本没有,统计出来的文件都很小,全家一起根本填不满磁盘。
所以在网上查了一下,然后自己模拟一遍记个笔记。

2.命令原理

2.1 df命令

df命令使用的是statfs这个系统调用,直接读取分区的超级块信息获取分区使用情况。它的数据是基于分区元数据的,所以只能针对整个分区。由于df直接读取超级块,所以运行速度不受文件多少影响。

2.2 du命令

du命令会对待统计文件逐个调用fstat,获取文件大小。它的数据是基于文件获取的,所以有很大的灵活性,不一定非要针对一个分区,可以跨越多个分区操作。如果针对的目录中文件很多,du速度就会很慢了。

3.情况模拟

首先查看当前磁盘情况,然后新建一个大小为1G的文件,模拟当时的日志。


模拟1.png

可以看到现在df和du命令查看结果是一致的。
模拟一下有某个程序占用这个文件,然后再将文件删除,看看结果如何。


模拟2.png

这次情况不一样了,df显示根目录下已经占用了19G,但du命令已经看不到那个1G的文件了。
根本原因在于tail程序占用了1G.file这个文件句柄,所以即便删除了这个文件,超级块信息也没有更新,df命令就查看不到删除文件后的磁盘情况。而du命令是对文件进行统计,文件在已经在文件系统中删除了,du命令自然查询不到。

只能停止占用句柄的程序,才能更新超级块的信息,类似的情况还有zookeeper的日志,直接使用重定向方式清空日志并不能释放空间,df命令查看依然是占用的,只能重启该节点的ZK。


模拟3.png

查看具体是哪个进程占用了文件,然后将其kill掉,再次使用df查看,其结果与du一致。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容