为什么有这么多种测量磁盘使用率的方法?


113

当我总结文件的大小时,我得到一个数字。如果我跑步du,我会得到另一个数字。如果我du在分区上的所有文件上运行,则与df使用的声明不匹配。为什么我的文件总大小有这么多不同的数字?电脑不能添加吗?

说到添加:当添加的“已使用”和“可用”列时df,我没有得到总数。总数小于我的分区的大小。而且,如果加总分区大小,我将无法获得磁盘大小!是什么赋予了?

Answers:


143

加起来很容易。问题是,要添加许多不同的数字。

文件使用多少磁盘空间?

基本思想是,包含n个字节的文件使用n个字节的磁盘空间,外加一些控制信息:文件的元数据(权限,时间戳等),以及系统所需的信息开销。查找文件的存储位置。但是,有很多并发症。

微观并发症

将每个文件想像成图书馆中的一系列书籍。较小的文件仅构成一个卷,而较大的文件则由许多卷组成,例如百科全书。为了能够找到文件,有一个卡目录可以引用每个卷。由于封面,每个卷都有一点开销。如果文件很小,则此开销相对较大。卡片目录本身也会占用一些空间。

再讲一点技术,在一个典型的简单文件系统中,该空间分为几个块。典型的块大小为4KiB。每个文件占用整数个块。除非文件大小是块大小的倍数,否则仅部分使用最后一个块。因此,一个1字节的文件和一个4096字节的文件都占用1个块,而4097字节的文件则占用2个块。您可以使用以下du命令进行观察:如果文件系统的块大小为4KiB,du则将报告1字节文件的4KiB。

如果文件很大,则仅需要额外的块来存储组成文件的块列表(这些是间接块;更复杂的文件系统可能会以扩展区的形式对此进行优化)。那些不会显示在ls -l或GNU 报告的文件大小中du --apparent-size; du,它报告了磁盘使用情况(而不是大小),说明了它们。

一些文件系统尝试重用最后一块中剩余的可用空间,以将多个文件尾部打包在同一块中。某些文件系统(例如,Linux 3.8之后的ext4)将0块用于完全适合inode的微小文件(仅几个字节)。

宏观并发症

通常,如上所述,报告的总大小du是文件使用的块或扩展数据块大小的总和。

du如果文件被压缩,报告的大小可能会更小。Unix系统传统上支持粗略的压缩形式:如果文件块仅包含空字节,则文件系统可以完全省略该块,而不必存储零块。具有这样的省略块的文件称为稀疏文件。当文件包含大量的空字节时,不会自动创建稀疏文件,应用程序必须安排文件变得稀疏。

一些文件系统(例如btrfszfs)支持通用压缩

晚期并发症

zfs和btrfs等非常现代的文件系统的两个主要功能使文件大小与磁盘使用率之间的关系更加遥远:快照和重复数据删除。

快照是文件系统在特定日期的冻结状态。支持此功能的文件系统可以包含在不同日期拍摄的多个快照。当然,这些快照会占用空间。在一个极端情况下,如果您从文件系统的活动版本中删除所有文件,则如果剩余快照,文件系统将不会为空。

自从快照以来或在两个快照之间进行任何更改后,未更改的任何文件或块在快照,活动版本或其他快照中都相同。这是通过写时复制实现的。在某些情况下,由于可用空间不足,可能无法在整个文件系统上删除文件-因为删除该文件将需要在目录中复制一个块,并且即使有一个块也没有空间。

重复数据删除是一种存储优化技术,包括避免存储相同的块。对于典型数据,寻找重复项并不总是值得的。无论 ZFS BTRFS支持重复数据删除作为可选功能。

为什么总数du与文件大小的总和不同?

如上所述,du每个文件报告的大小通常是文件使用的块或扩展数据块大小的总和。请注意,默认情况下,ls -l以字节为单位列出大小,但du在某些传统系统上以KiB或512字节单位(扇区)列出大小(du -k强制使用千字节)。大多数现代的unice支持ls -lhdu -h使用K,M,G等足以满足需要的“人类可读”数字(对于KiB,MiB,GiB)。

du目录上运行时,它将汇总目录树中所有文件(包括目录本身)的磁盘使用情况。目录包含数据(文件名以及指向文件元数据的指针),因此它需要一些存储空间。一个较小的目录将占用一个块,而较大的目录将需要更多的块。目录使用的存储量有时不仅取决于其包含的文件,还取决于插入文件的顺序以及删除某些文件的顺序(对于某些文件系统,这可能会留下漏洞-磁盘空间和性能之间的折衷),但差别很小(到处都是一个额外的方块)。当你跑步ls -ld /some/directory,列出目录的大小。(请注意,输出顶部的“总NNN”行ls -l是一个不相关的数字,它是所列项目的块大小之和,以KiB或扇区表示。)

请记住,du包括点文件,其ls不显示,除非您使用-A-a选项。

有时du报告少于预期的总和。如果目录树中存在硬链接,则会发生这种情况:du每个文件仅计数一次。

在某些文件系统(如ZFSLinux)上,du不会报告文件扩展属性占用的完整磁盘空间。

请注意,如果目录下有du挂载点,则除非指定了-x选项,否则也将计算这些挂载点上的所有文件。因此,例如,如果您想要根文件系统中文件的总大小,请运行du -x /,而不要运行du /

如果将文件系统挂载到非空目录,则该目录中的文件将被挂载的文件系统隐藏。他们仍然占据着自己的空间,但du找不到它们。

删除的文件

删除文件后,这只会删除目录条目,而不必删除文件本身。为了实际删除文件并因此回收其磁盘空间,必须满足两个条件:

  • 文件的链接数必须降至0:如果文件具有多个硬链接,则删除其中一个不会影响其他链接。
  • 只要通过某个进程打开文件,数据就保留下来。仅当所有进程都关闭文件后,该文件才会被删除。即使删除了文件,输出fuser -mlsof安装点上的文件也包含在该文件系统上打开文件的进程。
  • 即使没有进程打开已删除的文件,但如果该文件是loop设备的后端,则可能无法回收该文件的空间。losetup -a(如root)可以告诉您loop当前正在设置哪些设备以及在哪个文件上。在losetup -d可以回收磁盘空间之前,必须销毁循环设备(带有)。

如果您在某些文件管理器或GUI环境中删除文件,则该文件可能会被放入回收站区域,在该区域可以将其取消删除。只要可以删除该文件,它的空间仍会被占用。

这些数字df到底是什么?

典型的文件系统包含:

  • 包含文件(包括目录)数据和一些元数据的块(包括间接块和某些文件系统上的扩展属性)。
  • 免费块。
  • 保留给root用户的块。
  • 超级块和其他控制信息。
  • 索引节点
  • 一个日记

仅有第一种报告du。说到df“已使用”,“可用”和总计列中的内容取决于文件系统(当然,已使用块(包括间接块)始终位于“已使用”列中,而未使用块始终位于“已使用”列中)可用”列)。

ext2 / ext3 / ext4中的文件系统为root用户保留 5%的空间。这在根文件系统上很有用,可以在系统填满时保持系统正常运行(尤其是用于日志记录,并在解决问题时让系统管理员存储一些数据)。即使对于诸如的数据分区/home,保留几乎保留的空间也是有用的,因为几乎是完整的文件系统易于碎片化。Linux试图通过在写入文件时预分配许多连续的块来避免碎片化(这会减慢文件访问速度,特别是在旋转的机械设备(例如硬盘)上),但是如果连续的块不多,则无法工作。

创建文件系统时,传统的文件系统(包括ext4或以下)(不包括btrfs)会保留固定数量的inode。这显着简化了文件系统的设计,但缺点是需要适当确定inode的大小:如果inode太多,则会浪费空间;如果inode太少,则文件系统可能会先耗尽inode,然后再耗尽空间。该命令df -i报告正在使用多少个索引节点和多少个可用的索引节点(不适用该概念的文件系统可能报告为0)。

tune2fs -l在包含ext2 / ext3 / ext4文件系统的卷上运行将报告一些统计信息,包括空闲索引节点和块的总数以及数量。

另一个可能使问题感到困惑的功能是子卷(在btrfs和zfs中在名称数据集下受支持)。多个子卷共享相同的空间,但是具有单独的目录树根。

如果通过网络(NFS,Samba等)安装了文件系统,并且服务器导出了该文件系统的一部分(例如,服务器具有/home文件系统并导出/home/bob),则df在客户机上反映的是整个文件系统的数据,而不是仅用于导出并安装在客户端上的零件。

什么在使用磁盘上的空间?

如上所述,报告的总大小df并不总是考虑文件系统的所有控制数据。如果需要,请使用特定于文件系统的工具来获取文件系统的确切大小。例如,对于ext2 / ext3 / ext4,运行tune2fs -l并将块大小乘以块计数。

创建文件系统时,它通常会填充封闭分区或卷上的可用空间。有时,在四处移动文件系统或调整卷大小时,最终可能会得到一个较小的文件系统。

在Linux上,lsblk很好地概述了可用的存储量。有关其他信息,或者如果您没有该信息lsblk,请使用专门的卷管理或分区工具来检查您拥有的分区。在Linux上,还有的lvsvgspvsLVMfdisk传统PC风格(“MBR”)分区(以及GPT最近的系统),gdiskGPT分区,disklabel用于BSD的磁盘标签,分手等在Linux下,cat /proc/partitions给出了一个简单的总结。典型的安装至少有两个分区或操作系统使用的卷:文件系统(有时更多)和交换卷。

某些计算机的分区包含BIOS或其他诊断软件。带有UEFI的计算机具有专用的引导加载程序分区。

最后,请注意,大多数计算机程序使用的单位是1024 = 2 10的幂(因为程序员喜欢二进制和2的幂)。因此,1 kB = 1024 B,1 MB = 1048576 B,1 GB = 1073741824,1 TB = 1099511627776 B,…正式地,这些单位称为kibibyte KiB,mebibyte MiB等,但是大多数软件只报告k或kB, M或MB等。另一方面,硬盘制造商系统地使用公制(基于1000的单位)。因此1 TB驱动器仅为931 GiB或0.904 TiB。


1
@Kiwy tune2fs要求具有对包含文件系统的块设备的读取权限,通常需要具有root用户权限,因为这可以让您读取任何文件的内容。
吉尔斯2014年

20
我知道在SE中不鼓励使用“谢谢”,但是对于这个出色的职位,吉尔斯(Gills)值得您给予巨大的“谢谢”。
dotancohen 2014年

1
我记得6岁时看到过卡片目录,我想知道有多少人不知道它们是什么?
Izkata 2014年

1
@illuminÉ这对我来说Solaris太高级了,我不知道它适合什么级别。
吉尔斯2014年

1
du 确实说明了间接阻止。这是与所报告的文件大小的主要区别ls -l
斯特凡Chazelas

4

计算文件大小和磁盘空间的复杂性的简短摘要:

  • 文件在磁盘上占用的空间是其占用的块数乘以每个块的大小+占用的inode数的乘积。一个1字节长的文件将至少占用1个块,1个索引节点和一个目录条目。

    但是,如果该文件是到另一个文件的硬链接,则可能仅需要一个附加的目录条目。这将只是对同一组块的另一种引用。

  • 文件内容的大小。这就是ls显示的内容。
  • 可用磁盘空间不是您可以容纳的最大文件的大小,也不是磁盘上将适合的所有文件内容大小的总和。它介于两者之间。它取决于块大小的文件数量(占用inode)以及每个文件的内容完全填充块的紧密程度。

这只是在刮擦文件系统的表面,并且过于简化。还请记住,不同的文件系统以不同的方式运行。

stat在发现某些此类信息方面非常有帮助。以下是一些有关如何使用stat及其优点的示例:http : //landoflinux.com/linux_stat_command_examples.html


1
一个1字节的文件通常占用一个块,而不是8。创建硬链接根本不会创建一个索引节点:无论与该文件有多少链接,一个文件就是一个索引节点。创建硬链接仅需要目录条目的空间。
吉尔斯

感谢您所做的更正,诚然,我的记忆还是这样:深入研究ext2现在有点模糊。我正在关注stat re:阻止计数的输出-确实感觉过多,但这就是问题所在。我会改正答案。
Pedro

1
这是因为,如果ext2文件系统使用4kB块,则1个ext2块= 8个统计块:出于历史原因,统计以512字节块为单位。参见unix.stackexchange.com/questions/14409/…–
Gilles

2

我将在此处说明导致du与的不同的不同情况df

df计算文件系统分配的块数,du使用每个文件的大小信息。差异可能有很多原因:

1)仍由应用程序打开的未链接(删除)的文件。文件信息丢失,仍分配该块。 lsof +aL1 <filesystem>将帮助您确定流程。大多数时候,您必须杀死进程以释放空间(取决于进程,有时重新加载配置就足够了)。

2)安装点下面的文件隐藏到,du但没有隐藏到dfdebugfs可以帮助您读取文件系统。

$ sudo debugfs 
debugfs 1.42.12 (29-Aug-2014)
debugfs:  open /dev/xxx    (the desired file system  device)
debugfs:  cd /boot
debugfs:  ls -l 
 1966081   40755 (2)      0      0    4096 26-May-2016 16:28 .
      2   40555 (2)      0      0    4096 11-May-2016 10:43 ..
 1974291  100644 (1)      0      0       0 26-May-2016 16:28 bob   <---<<< /boot/bob is hidden by /boot fs

3)看起来比实际大的稀疏文件。未分配的块不计入,df但表观文件大小由计入du

请注意,硬链接不会傻瓜 du


2

df通常用于查看文件系统是什么,每个文件系统有多完整以及它们的安装位置。当文件系统空间不足时,可能需要在文件系统之间移动东西或购买更大的磁盘等时,此功能非常有用。

du显示每个目录消耗多少累积存储的详细信息(类似于windirstatWindows)。非常适合在尝试执行文件清理时找到要占用空间的位置。

除了其他人解释的较小的数字差异外,我认为dudf实用程序的用途也非常不同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.