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一致。