问题描述
执行df
和du
命令时候出,现两者相差数值较大如下所示:
[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为要删除的文件,一般这种场景为清空日志文件之类,则执行这个命令 如果您有其他问题,欢迎您联系火山引擎技术支持服务