linux下du和df结果不一致的原因及处理

1. 原理介绍

1 .1du 的工作原理

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

1.2 df 的工作原理

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

2. 实验模拟

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

首先查看磁盘和路径

[root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   42G   201G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

[root@zhjk115 app]#

[root@zhjk115 app]# pwd

/app

dd 命令创建 1G 大学的文件

[root@zhjk115 app]# dd if=/dev/zero of=/app/test.iso bs=1024k count=1000

1000+0 records in

1000+0 records out

1048576000 bytes (1.0 GB) copied, 4.31891 s, 243 MB/s

查看 df 和 du 结果,目前是一致的

[root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   43G   200G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

[root@zhjk115 app]# du -sh

43G

模拟进程在使用 test.iso 文件

[root@zhjk115 app]# tail -f test.iso &

[1] 22349

[root@zhjk115 app]# ps -ef |grep tail

root     22349 21633 28 09:56 pts/1    00:00:01 tail -f test.iso

root     22353 21633  0 09:56 pts/1    00:00:00 grep tail

删除 test.iso 文件, 可以看出 df 和 du 的结果是不一致的

[root@zhjk115 app]# rm -rf test.iso

 [root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   43G   200G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

 [root@zhjk115 app]# du -sh

42G

用 lsof 查看哪个进程在使用 /app/test.iso

[root@zhjk115 app]# lsof |grep test.iso

tail   22349   root    3r   REG   253,2 1048576000  12 /app/test.iso

手动 kill 占有 test.iso 文件的进程,此时, du 和 df 的结果一致

[root@zhjk115 app]# kill -9 22349

[1]+  Killed                  tail -f test.iso

[root@zhjk115 app]# du -sh

42G 

[root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   42G   201G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

   

结论:

本实验主要是针对Linux环境的使用,该问题是由于进程的文件句柄释放问题导致的,很多情况为清理完日志等文件是du显示为已释放空间,但df空间还在使用,此时可以通过echo(或者>)代替rm来避免这种情况,同时也可以查看是哪个进程在使用,可以根据情况手动清理、重启应用或者等待释放。

注:当oracle主机某些日志被清理后但df显示空间没有被释放也是同样的道理,一般来说等一段时间即可,否则需要重启数据库实例来释放空间。

1,两者区别     
       du,disk usage,是通过搜索文件来计算每个文件的大小然后累加,du能看到的文件只是一些当前存在的,没有被删除的。他计算的大小就是当前他认为存在的所有文件大小的累加和。

       df,disk free,通过文件系统来快速获取空间大小的信息,当我们删除一个文件的时候,这个文件不是马上就在文件系统当中消失了,而是暂时消失了,当所有程序都不用时,才会根据OS的规则释放掉已经删除的文件, df记录的是通过文件系统获取到的文件的大小,他比du强的地方就是能够看到已经删除的文件,而且计算大小的时候,把这一部分的空间也加上了,更精确了。
        当文件系统也确定删除了该文件后,这时候du与df就一致了

工作中需要注意的地方:
1.当出现du和df差距很大的情况时,考虑是否是有删除文件未完成造成的,方法是lsof |grep delete命令,然后停止相关进程即可。
2.可以使用清空文件的方式来代替删除文件,方式是:echo > myfile.iso。
3.对于经常发生删除问题的日志文件,以改名、清空、删除的顺序操作。
4.除了rm外,有些命令会间接的删除文件,如gzip命令完成后会删除原来的文件,为了避免删除问题,压缩前先确认没有进程打开该文件。

发布了6 篇原创文章 · 获赞 30 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/boyemachao/article/details/103922772