如何排查df和du显示的磁盘空间使用情况不一致的问题

计算操作系统技术服务知识库
问题描述

执行dfdu命令时候出,现两者相差数值较大如下所示:

[root@dudf ~]# df -h /dev/vdb 
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb         20G  3.0G   16G  17% /tmp
[root@dudf ~]# du -sh /tmp/
20K     /tmp/
问题分析

df 和du 的工作原理

du的工作原理

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

df的工作原理

df命令使用的是statfs这个系统调用,直接读取分区的超级块信息获取分区使用情况。它的数据是基于分区元数据的,所以只能针对整个分区。

du和df不一致情况

常见的df和du不一致情况就是文件删除的问题。当一个文件被删除后,在文件系统 目录中已经不可见了,所以du就不会再统计它了。然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除, 分区超级块中的信息也就不会更改。这样df仍旧会统计这个被删除了的文件。

解决方案

方法一

切换至“相关目录”,执行命令lsof |grep deleted,查询处于deleted状态的文件,被删除的文件在系统中被标记为deleted。如果系统中存在大量deleted状态的文件,会导致du和df命令统计结果不一致,如下所示:

[root@dudf ~]# lsof |grep deleted
tail      1284         root    3r      REG             253,16 3145728000         12 /tmp/test.iso (deleted)

参考lsof命令列出的PID,执行命令kill -9 [$PID],使用kill命令结束相应进程,或者重启相应的服务,如下所示:

kill -9 15020

查看df与du的值是否匹配如下所示:

[root@dudf ~]# du -sh /tmp/
20K     /tmp/
[root@dudf ~]# df -h /dev/vdb 
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb         20G   45M   19G   1% /tmp

方法二

重启实例,系统会退出现有的进程,开机后重新加载服务,此过程中会释放调用的deleted文件的句柄。

如何避免此类问题

可以使用清空文件的方式来代替删除文件:

echo > myfile

myfile为要删除的文件,一般这种场景为清空日志文件之类,则执行这个命令 如果您有其他问题,欢迎您联系火山引擎技术支持服务

50
0
0
0
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论