一般情况下Linux系统里df显示的也会比du显示的略大些,原因如下:
df命令通过查看文件系统磁盘块分配图计算出总块数与剩余块数。
文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如i节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,通常称为Meta
Data。
du命令是用户级的程序,它不考虑Meta Data,而df命令则查看文件系统的磁盘分配图并考虑Meta Data。
有时删除了大的日志文件出现df和du值差异很大的情况一般是由于有进程在向文件中写数据或有进程正在访问文件。
例如在删除.tran.log.swp文件后使用df和du命令
[root@500 termic]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg01-lveasylink
5.0G 3.8G 914M 81%
/home/ap/easylink
[root@500 termic]# cd /home/ap/easylink/
[root@HBAPQ500 easylink]# du -sh
2.4G .
两者计算值差3.8G-2.4G=1.4G的大小
于是使用lsof命令发现
[root@500 easylink]# lsof /home/ap/easylink
COMMAND PID USER FD TYPE
DEVICE SIZE NODE NAME
vim 27344
easylink 4u REG 253,10 1499705344 215879
/home/ap/easylink/publish/log/termic/.tran.log.swp
(deleted)可以看出Vim进程还在打开这个文件,即使此时文件已被rm,可以看出此文件大小正对应着df和du输出的差值(1499705344/1024/1024/1024即1.4G)
造成差异的原因是:
当某程序在后台打开了某个文件时,例如vi,只要该进程保持打开或仍在运行,即使将该文件删除,此时运行df和du会显示较大的差异,除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点(inode)。
因为当进程打开一个文件,会得到一个指针。随后对这个文件的写操作会引用这个指针。写操作不会检查该文件是否存在。它只是写入指定数量的字符在预定的位置。无论文件存在与否,磁盘块被写操作使用。df命令计算已使用的磁盘块的数量,而du通过文件结构、inode信息和每个目录使用的块的数字来计算。作为据du而言,被进程使用的文件不存在,所以它不会计算块使用这个幽灵的文件。但df跟踪磁盘块使用,它会计算上这个幽灵的文件所使用的块。
(当一个应用程序正在写一个大文件的时候,我们RM或者MV了这个文件(UNIX是允许这么干的,WINDOWS在这一点上当然是不行的),应用程序会占有句柄,并根据句柄所指磁盘位置直接写磁盘,而不会检查该文件是否被删除。)
结论:
1.文件系统的陡涨的原因是非正常退出vi大文本文件会导致产生大的swp文件。
2.rm不释放空间的原因即为有vi进程在打开这个swp文件(即使此文件已删除)而引起操作系统认为这个文件未实质释放,从而df统计时计算了该swp文件部分导致空间统计不正确。这一类问题让其立即释放的解决方法可以重启操作系统或重新umount及mount那个文件系统,但此操作需停应用。另可以杀掉deleted进程或等该进程消失后空间后自动释放。
后续建议:
1.vi大文件的日志后建议正常退出。
2.清理log这些文本日志文件时最好用">
文件"这样的操作方式,不要用rm,这样会导致df监控在近一段时间会认为文件系统比实际占用率高。
=============
PS附上关于df和du的输出差别原文解释:
Problem Definition
------- ----------
This section gives the technical explanation of why du and df
sometimes report
different totals of disk space usage.
When a program that is running in the
background writes to a file while the
process is running, the file to which this process is writing is
deleted.
Running df and du shows a discrepancy in the amount of disk space
usage. The
df command shows a higher value.
Explanation Summary
----------- -------
When you open a file, you get a pointer. Subsequent writes to this
file
references this file pointer. The write call does not check to see
if the file
is there or not. It just writes to the specified number of
characters starting
at a predetermined location. Regardless of whether the file exist
or not, disk
blocks are used by the write operation.
The df command reports the number of disk blocks used, while du
goes through the
file structure and reports the number of blocks used by each
directory. As
far as du is concerned, the file used by the process does not
exist, so it does
not report blocks used by this phantom file. But df keeps track of
disk blocks
used, and it reports the blocks used by this phantom
file.