为什么df和du所查看到的已使用的磁盘容量不同?

时间:2021-07-05 18:30:34

 

*******************************************************************************************

版权所有: www.foutime.com  深圳市方泰智能科技有限公司   

通道锁 逃生锁 一卡通 楼宇对讲 停车场

*******************************************************************************************

 

1. du

The du user command gives the number of kilobytes contained in all files and, recursively, directories within each specified directory or file (filename). (针对的文件或目录)

(1) 使用方式

l 直接输入du

不加任何参数时,du会分析当前所在目录的文件与目录所占用的硬盘空间。但是,实际显示时,仅会显示目录容量(不显示文件容量),此外输出的数值数据为1k大小的单位。如:

为什么df和du所查看到的已使用的磁盘容量不同?

我们看到在VMShare目录下执行du,结果仅将VMShare中子目录的容量列出来,而没有列出文件的容量。注意:最后一行显示当前目录的容量并不等于上面所有容量的加和,正是因为最后一行的容量还包含了没有显示出的文件所占的容量。

我们在VMShare目录下创建一个新目录Test,并将Server和Client目录复制一份到Test中,然后进入Test中运行du查看结果,如下:

为什么df和du所查看到的已使用的磁盘容量不同?

我们看这个时候最后一行所列结果就等于上面两行容量的加和了,原因是因为Test目录中没有直接文件。我们在退回VMShare执行du,结果如下:

为什么df和du所查看到的已使用的磁盘容量不同?

根据这个结果我们能得到如下结论:

a. 如果有子目录,du会递归遍历子目录,统计列出子目录的大小。

b. 观察结果的5、6、7行,我们发现du会将子目录的容量重复计算,所以导致最终结果(最后一行的容量)小于之前所有子目录容量的加和。

l -S

加-S(大写),则目录的容量不再包含子目录的容量,如:

为什么df和du所查看到的已使用的磁盘容量不同?

我们发现添加-S后Test的容量变为0,这是因为Test中没有直接文件,只有目录。

l -h

以人们较容易读的容量格式(K/G/M)显示。如:

为什么df和du所查看到的已使用的磁盘容量不同?

l -s

只列出当前目录的容量(单位K),不包括子目录的统计。如:

为什么df和du所查看到的已使用的磁盘容量不同?

(2) 原理
du命令会对待统计文件逐个调用fstat这个系统调用
(有子目录会递归调用),获取文件大小。运行较慢

int fstat(int fd, struct stat *buf);

fd 规定要检查的打开文件的文件描述符

buf 是struct stat结构体类型的变量

查看的是inode信息。

2. df

The df user command displays the following information:
amount of disk space occupied by currently mounted file systems
;
the amount of used and available space
;
how much of the file system's total capacity has been used
; (针对的是文件系统)

(1) 用法

l 不加任何参数

在linux下如果df不加任何参数,那么默认会将系统内的所有文件系统信息(不含特殊的内存内的特殊文件系统和swap),都以1KB的容量列出来。如下图所示。

为什么df和du所查看到的已使用的磁盘容量不同?

l -h

以人们较易阅读的GB、MB、KB等合适自行显示。如图:

为什么df和du所查看到的已使用的磁盘容量不同?

注意:Used的容量和Avail的容量相加要小于文件系统的总容量(Size),这是因为文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如i节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,通常称为Meta Data。

l 目录或文件做参数

在df后加上目录或文件时,df会自动分析该目录或文件所在的文件系统,并将该文件系统的信息列出来。如下图所示。

为什么df和du所查看到的已使用的磁盘容量不同?

注:VMShare是windows与linux的共享文件夹。

说明:如果除了Meta Data所占空间,Used空间已达上限,则只有超级用户可以再创建文件,分配新的block,这将导致当前文件系统的使用率超过百分之百。

(2) 原理

df命令使用的事statfs这个系统调用,直接读取分区的超级块信息获取分区使用情况,所以执行速度很快。
int fstatfs(int fd, struct statfs *buf);

fd: 需要查询信息的文件系统的文件描述词

buf:以下结构体指针变量,用于储存文件系统相关的信息

struct statfs {

long f_type; /* 文件系统类型 */

long f_bsize; /* 经过优化的传输块大小 */

long f_blocks; /* 文件系统数据块总数 */

long f_bfree; /* 可用块数 */

long f_bavail; /* 非超级用户可获取的块数 */

long f_files; /* 文件结点总数 */

long f_ffree; /* 可用文件结点数 */

fsid_t f_fsid; /* 文件系统标识 */

long f_namelen; /* 文件名的最大长度 */

};

df查看的superblock的信息。

3. 为什么du和df有时列出的磁盘空间会不同?

为什么df和du所查看到的已使用的磁盘容量不同?

l 原因一

du 命令只计算被文件占用的空间。不计算文件系统metadata 占用的空间,如inodes, inode maps, 或者disk maps。

l 原因二

当一个文件被执行删除操作,但是删除前有其他进程持有该文件的句柄时,由于此时该文件所占用的block并没有被释放,所以df仍然会统计该文件的容量,但是du不会再遍历到该文件,所以不会将该文件所占的空间统计在内。

结论:对已使用的空间统计,df的结果要大于du的结果。