为什么磁盘使用量大于其上所有文件的大小?

osh*_*nen 10 partitioning ext4 hard-drive

我有一个 3TB 的硬盘。在硬盘的属性屏幕上,它说我已经使用了471.4GB,但是当我选择nautilus中的所有文件时,它说选择了321.0GB。如果我的硬盘中只有 321.0GB 的文件,为什么它使用 471.4GB?

硬盘的分区使用的是 EXT4 中使用的 GUID 和文件系统。当我使用磁盘工具应用程序选择硬盘时,我收到一条警告:

WARNING: The partition is misaligned by 3072 bytes.
This may result in very poor performance.  Repartitioning is suggested.
Run Code Online (Sandbox Code Playgroud)

这与缺少 150.4GB 有什么关系吗?

ger*_*ijk 17

磁盘上的文件有两种大小:“表观大小”和“磁盘大小”。有几个原因可能会导致较大的差异:

  • 大量的文件会导致大量的开销,因为内部碎片。例如,Ext4 的默认块大小为 4KiB;小于该值的文件将始终消耗 4KiB,并且上面的大小将“四舍五入”到此块对齐。
  • 目录也是文件,同样的规则也适用于它们。此外,如果您要在目录中创建大量文件,然后再次删除它们,则无法回收对目录文件的使用(重新创建目录有帮助)。
  • 稀疏文件是特殊文件,看起来很大,但不会“消耗”空间。这在虚拟磁盘映像的虚拟化中很常见;它们看起来很大,但“真实”的尺寸可能要小得多。许多实用程序(和文件管理器)无法显示实际磁盘使用情况。
  • 硬链接的使用。当多个引用指向它时,文件的内容可以存在于磁盘上。一些文件管理器可能会考虑每个参考的大小。

我建议使用已知能够列出两​​种大小的磁盘使用工具来查看这是否是问题所在。ncdu在终端中尝试并使用a在实际使用和磁盘使用之间切换。


由于使用 4KiB 块大小的文件系统而导致的内部碎片的简短演示du

$ sudo tune2fs -l /dev/path-to-device | grep "Block size"
Block size:               4096

$ echo blaataaap > myfile                      # creates a 10-byte file

$ du --block-size=1 myfile                     # prints the usage on disk (filesystem)
4096   myfile

$ du --apparent-size --block-size=1 myfile     # prints the apparent size, i.e.
10     myfile                                  # content length when seeking

$ ls -al
-rw-rw-r-- 1 gert gert 10 Jan 1 23:24 myfile   # ls uses apparent sizes
Run Code Online (Sandbox Code Playgroud)

这意味着这个 10 字节的文件在磁盘上比它在列表中显示的要大 4086 字节,并且存在内部碎片。


关于硬链接和磁盘使用情况的简短演示在列出文件时显示错误(ls在本例中):

$ dd if=/dev/zero of=1MBfile bs=1M count=1 # create a 1MB file
$ ln 1MBfile a_hard_link                   # create a hard link to it

$ ls -alht                                 # ls will report 2MB
total 2.1M
drwxrwxr-x  2 gert gert 4.0K Jan  2 11:21 .
-rw-rw-r--  2 gert gert 1.0M Jan  2 11:21 1MBfile
-rw-rw-r--  2 gert gert 1.0M Jan  2 11:21 a_hard_link

$ du -B 1024 .                             # du reports 1028K total for directory
1028    .

$ du -B 1024 a_hard_link                   # and 1024K for each file individually
1024    a_hard_link
$ du -B 1024 1MBfile
1024    1MBfile
Run Code Online (Sandbox Code Playgroud)