首页 > 代码库 > du与df区别以及出现较大差距时解决方法

du与df区别以及出现较大差距时解决方法

  在linux下查看磁盘使用率,最常用到的是df和du,但是有时就会发现du 和df出来的结果并不完全相同,有时候还有很大差距

1. 两个命令的解释  

  du  --disk usage

  df  -- disk free

2.du 和df 工作原理

2.1 du工作原理

  du命令会对待统计的文件逐个调用fstat这个系统调用,来获取文件大小。它的数据是基于文件获取的,有很大的灵活性。不一定非

要针对一个分区,可以跨多个分区操作,如果针对的目录中文件的个数较多,du的速度就会很慢了。

2.2 df 工作原理

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

正因为df读取的是超级块,所以运行速度不受文件数量的影响。

3.du和df不一致情况模拟

  常见的df和du不一致就是文件删除的问题。当一个文件被删除后,在文件系统目录中已经不存在了,所以du就不再统计该文件。但是如果

此时还有运行的程序持有这个已经被删除的文件的句柄,那么这个文件就不会真正的在磁盘中被删除,分区的超级块中信息也就不会更改,所以

df还会统计这个已经被删除了的文件。

(1)当前根分区的使用情况

[root@vrh1 ~]# df -h /Filesystem            Size  Used Avail Use% Mounted on/dev/mapper/VolGroup00-LogVol00      28G   14G   12G  54% /

(2)创建一个1G的文件

[root@vrh1 ~]# dd if=/dev/zero of=test.log bs=1024k count=10241024+0 records in1024+0 records out1073741824 bytes (1.1 GB) copied, 14.2389 seconds, 75.4 MB/s

(3)此时根分区的使用情况

  df查询结果

[root@vrh1 ~]# df -hFilesystem            Size  Used Avail Use% Mounted on/dev/mapper/VolGroup00-LogVol00     28G   15G   11G  58% //dev/sda1              99M   13M   82M  14% /boottmpfs                1006M     0 1006M   0% /dev/shm

  du查询结果

[root@vrh1 ~]# pwd/root[root@vrh1 ~]# du -sh1.1G    .

  此时的二者的查询结果基本相同

(4)模拟一个进程打开这个文件,然后删除这个文件

[root@vrh1 ~]# tail -f test.log &[1] 2880[root@vrh1 ~]# [root@vrh1 ~]# rm -fr test.log 

(5)再次对比du和df 的结果

首先确认有进程持有test.log的句柄

[root@vrh1 ~]# lsof | grep test.logtail      2880      root    3r      REG              253,0 1073741824    2254399 /root/test.log (deleted) #注意在这里可以看到这个文件已经被删除了
[root@vrh1 ~]# df -hFilesystem            Size  Used Avail Use% Mounted on/dev/mapper/VolGroup00-LogVol00                       28G   15G   11G  58% //dev/sda1              99M   13M   82M  14% /boottmpfs                1006M     0 1006M   0% /dev/shm[root@vrh1 ~]# du -sh888K    .

可以看到df没有发生变化,而du则不再统计这个被删除了的文件

(6)停止模拟进程,再次对比du和df结果

[root@vrh1 ~]# kill -9  2880[root@vrh1 ~]# [1]+  Killed                  tail -f test.log[root@vrh1 ~]# lsof | grep test.log[root@vrh1 ~]# 
[root@vrh1 ~]# df -hFilesystem            Size  Used Avail Use% Mounted on/dev/mapper/VolGroup00-LogVol00                       28G   14G   12G  54% //dev/sda1              99M   13M   82M  14% /boottmpfs                1006M     0 1006M   0% /dev/shm[root@vrh1 ~]# du -sh888K 

此时test.log文件已经没有进程占有它了,也就从磁盘上删除了,分区的超级块信息已经更改,df也就显示正常了

 4.日常使用中需要注意的地方

(1)当出现du和df有很大差距的时候,考虑是否有删除文件未完成造成的,方法是lsof命令,然后停止相关进程即可(即使用lsof中文件末尾标明deleted的)

(2)可以使用清空文件的方式来替代删除文件,方式是:echo > test.log

(3)对于经常发生删除问题的日志文件,以改名、清空、删除的顺序来操作

(4)除了 rm 外,有些命令会间接的删除文件,如gzip命令完成后会删除原来的文件,为了避免删除问题,压缩前先确认没有进程打开该文件

(5)查看已经被 rm 掉,但是仍然被进程占用的文件的方法 :lsof | grep deleted

 

 

 

 

参考链接:http://blog.csdn.net/smstong/article/details/8715650

注:虽然基本照搬原链接内容,但是自己在实际测试中,还是有些额外的收获和体会的。

du与df区别以及出现较大差距时解决方法