df -h 给出假数据?

df -h giving fake data?

当我在我的实例中写入 df -h 时,我得到了这些数据:

Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        7.7G     0  7.7G   0% /dev
tmpfs           7.7G     0  7.7G   0% /dev/shm
tmpfs           7.7G  408K  7.7G   1% /run
tmpfs           7.7G     0  7.7G   0% /sys/fs/cgroup
/dev/nvme0n1p1   32G   24G  8.5G  74% /
tmpfs           1.6G     0  1.6G   0% /run/user/1000

但是当我点击 sudo du -sh / 我得到:

11G /

所以在 df -h 中,/ 大小是 24G 但在 du -sh 相同目录中大小是 11G。 我试图在我的实例上获得一些免费的 space,但找不到导致该问题的文件。 我缺少什么? df -h 真的提供假数据吗?

这个问题经常出现。文件系统在文件系统中分配磁盘块来记录它的数据。此数据称为元数据,对大多数用户级程序(例如 du)不可见。元数据的示例有索引节点、磁盘映射、间接块和超级块。

du 命令是一个不了解文件系统元数据的用户级程序,而 df 查看文件系统磁盘分配映射并了解文件系统元数据。 df 获得真实的文件系统统计信息,而 du 只能看到部分图片。

当运行使用 du 或 df 命令不同时,使用或可用磁盘 space 的原因有很多。

也许最常见的是删除文件。已删除的文件可能仍被至少一个进程打开。此类文件的条目已​​从关联目录中删除,这使得文件无法访问。因此,仅对文件进行计数的命令 du 不会将这些文件考虑在内,而是得出一个较小的值。但是,只要进程仍在使用已删除的文件,相关块就不会在文件系统中释放,因此在内核级别运行的 df 会正确地将这些块显示为已占用。您可以通过 运行 执行以下操作来确定是否属于这种情况:

lsof | grep '(deleted)'

此问题的解决方法是重新启动仍打开那些已删除文件的服务。

第二个最常见的原因是如果您有一个分区或驱动器安装在同名目​​录的顶部。例如,如果您在 / 下有一个名为 backup 的目录,其中包含数据,然后您在该目录的顶部安装一个新驱动器并将其标记为 /backup 但它不包含任何数据,那么使用的 space 将显示为df 命令,即使 du 命令不显示任何文件。

要确定是否有任何文件或目录隐藏在活动挂载点下,您可以尝试使用绑定挂载来挂载您的 / 文件系统,这将使我能够检查其他挂载点下方。请注意,仅建议有经验的系统管理员使用此方法。

mkdir /tmp/tmpmnt
mount -o bind //tmp/tmpmnt
du /tmp/tmpmnt

确认这是问题所在后,可以通过 运行ning 删除绑定安装:

umount /tmp/tmpmnt/
rmdir /tmp/tmpmnt

另一个可能的原因可能是文件系统损坏。如果怀疑存在这种情况,请确保您有良好的备份,并在方便时卸载文件系统并 运行 fsck。

同样,这应该由有经验的系统管理员完成。

你也可以通过运行ning查看计算:

strace -e statfs df /

这会给你类似的输出:

statfs("/", {f_type=XFS_SB_MAGIC, f_bsize=4096, f_blocks=20968699, f_bfree=17420469, 
f_bavail=17420469, f_files=41942464, f_ffree=41509188, f_fsid={val=[64769, 0]}, 
f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda1 83874796 14192920 69681876 17% /
+++ exited with 0 +++

注意到 f_bfree 和 f_bavail 之间的区别了吗?这些是文件系统中的空闲块与非特权用户可用的空闲块。使用的列只是两者之间的计算。

希望这能让你的想法更清晰。如果您还有任何疑问,请告诉我。