# du-df磁盘使用不一致

## Linux，du、df统计的硬盘使用情况不一致问题

在运维Linux服务器时，会碰到需要查看硬盘空间的情况，这时候，通常会使用df -lh命令来检查每个挂载了文件系统的硬盘的总量和已使用量，或者，可以使用du -sh \[directory]命令来统计某个目录下所有文件的空间占用。

在使用df、du命令时，常常会遇到统计的硬盘使用情况不一致的问题。比如du统计根目录下文件总共大小为2G，而df判断挂载在根目录的硬盘已用空间达到了3G，20G甚至更多。发生这种情况，有以下三种原因：

## 预留空间

为了预防紧急情况，linux ext文件系统会预留部分硬盘空间，具体预留的数值可以通过tune2fs -l \[dev\_name] | grep “Reserved block count”查看到（dev\_name是设备名），这里预留的空间会被df计算到已用空间中，从而导致df和du统计不一致。如果需要调整预留空间大小，我们可以使用tune2fs -m \[size]\[dev\_name]来进行调整。

## 幻影文件（phantom file）

du是统计被文件系统记录到的每个文件的大小，然后进行累加得到的大小，这是通过文件系统获取到的。而df主要是从超级块（superblock）中读入硬盘使用信息，df获取到的是磁盘块被使用的情况。当一个文件被删除时，如果有别的进程正在使用它（占有句柄）， 这个文件将不会被du统计到，但是这个文件被占用的磁盘空间却依然会被df统计到。这些文件，以及正在使用这些文件的进程可以通过lsof | grep deleted查到。当进程停止或者被kill时，这些空间将被释放。

## 未统计到的文件

如果上面两种情况都排除了，但是数据还是不一致，那是怎么回事？这里隐藏着一种情况：当我们将一个目录挂在到一个新的设备（硬盘）上之前，如果这个目录里面已经有数据，那么这一部分数据不会被du感知，在文件系统中也看不到这些数据，但是这些数据又是确实占用了磁盘空间，是能够被df所统计到的。这时候通过du/df统计原设备的空间使用情况，就会发现df统计到的比du要多。遇到这样的情况时，使用fuser -km \[directory]杀死占用该目录的所有进程（小心操作！），然后使用umount \[directory]将该目录挂载的设备卸载，这时，目录里面原来已有的数据就会出现，我们将其删除之后，再重新挂载设备（mount -t \[type]\[dev] \[directory]）即可。
