发现一台用户的电脑,df检查出来的/磁盘空间占用了16G,比用du查看得到的磁盘空间大的多,du查看/下所有程序目录加起来还不到5G。这是什么原因呢?

即便是有隐藏文件,查了也很小啊。


一、df和du的统计机制:

    1、du会把指定目录下所有文件、目录、目录下的文件都统计。是建立在文件系统能看到的的确确是有这样一些文件的基础上的。也就是说我们能在文件系统里面看到的文件才会被du统计。

    2、df(df命令通过查看文件系统磁盘块分配图得出总块数与剩余块数。):

       

       这要从程序写文件的方式来谈起,一个进程要向一个文件里面写东西,那么会得到一个pointer,

然后向指针指向的文件(磁盘区域)写入。假如由于某些原因(也可能人为)被指向的文件被删除了,但是( write call)并不知道文件是否还在,就还会继续向里面写,不管文件是否存在,磁盘块还是被写操作使用。

于是因为文件没有了,所以du统计不到写入的这些磁盘块,但是因为写的进程还在,磁盘空间没有被释放,所以df却能统计到,所以df统计的结果比du大很多。

如何解决呢?

1.停止系统上的程序。

2.如果还是不行,unmount一下文件系统看看

3.重启系统


二、ls和du统计机制:

      一个文件占用的磁盘空间和一个文件的大小是两码事情。

      占用空间取决于文件系统的块(block)的大小,linux一般默认是4k(4096),因此,一个大小为1个字节的文件,最小也要占用4k,如果你创建文件系统的时候制定块大小是16K,那么即便一个文件只有1个字节,占用空间也是16K。
      如果一个分区上主要放大文件,那么block可以大一些,有利于减少磁盘碎片,如果主要放小文件,那么block设置小一下,否则太浪费磁盘空间。
      通常情况下,ls 显示的文件大小比du显示的磁盘占用空间小

      原因:   比如文件系统的block是4K,一个13K的文件占用的空间是 13k/4k = 3.25个block,一个block只能被一个文件占用,因此实际占用空间就是4个block,就是16K。


      如果一个文件有比较大的黑洞,那么会出现文件大小比磁盘空间占用大的情况

      原因:   首先要理解什么是黑洞,怎么才能产生黑洞?

         在向一个文件中写数据的时候,文件偏移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将加长该文件,并在文件中构成一个空洞,这一定是允许的。位于文件中但没有写过的字节都被读为0.   文件中的空洞并不要求在磁盘上占用存储区。具体处理方式与文件系统的实现有关,当定位超出文件尾端之后写时,对于新写的数据需要分配磁盘块,但是对于原文件尾端和新开始写位置之间的部分则不需要分配磁盘块。

    稀疏文件--文件中有“洞”(hole)的文件

用Shell也可以创建稀疏文件:

$ dd if=/dev/zero of=sparse_file.img bs=1M seek=1024 count=0
0+0 records in
0+0 records out

查看方法:

 ls -s  : 反应磁盘分配情况,非实际文件大小,以block为单位    == du
 ls -lh : 反应实际文件大小    == du --apparent-size