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

说到添加:当我添加df的“ Used”和“ Available”列时,我没有得到总数。而且这个总数小于我分区的大小。而且,如果加总分区大小,我将无法获得磁盘大小!有什么作用?

#1 楼

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

文件使用多少磁盘空间?

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

微观并发症

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

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

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

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

宏观上的并发症

如上所示,du报告的总大小是文件使用的块或扩展区大小的总和。

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

某些文件系统(例如btrfs和zfs)支持通用压缩。

高级并发症

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

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

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

重复数据删除是一种存储优化技术,包括避免存储相同的块。对于典型数据,寻找重复项并不总是值得的。 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时,将列出目录的大小。 (请注意,ls -l输出顶部的“总NNN”行是无关的数字,它是所列项目的块大小总和,以KiB或扇区表示。)

请记住,除非您使用duls选项,否则-A会包含-a不会显示的点文件。

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

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

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

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

已删除的文件

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


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

如果您在某些文件管理器或GUI环境中删除文件,则可能会将其放入回收站,以备不时之需。不删除。只要文件可以被删除,它的空间仍然会被占用。

df的确切数字是什么?

典型的文件系统包含:


包含文件(包括目录)数据和一些元数据(包括间接块和某些文件系统上的扩展属性)的块。
空闲块。
保留给root用户的块。
超级块和其他控制信息。
Inodes
日志


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

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

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

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

另一个可能引起混淆的功能是子卷(在btrfs和zfs中受名称数据集支持)。多个子卷共享相同的空间,但是具有单独的目录树根。

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

空间的使用情况在我的磁盘上?

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

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

在Linux上,lsblk很好地概述了可用的存储卷。有关其他信息,或者如果您没有lsblk,请使用专门的卷管理或分区工具来检查您拥有的分区。在Linux上,用于LVM的lvsvgspvs,用于传统PC样式(“ MBR”)分区(以及最新系统上的GPT)的fdisk,用于GPT分区的gdisk,用于BSD磁盘标签,Parted的disklabel。 ,cat /proc/partitions提供了一个简短的摘要。典型的安装至少具有操作系统使用的两个分区或卷:文件系统(有时更多)和交换卷。某些计算机的分区包含BIOS或其他诊断软件。具有UEFI的计算机具有专用的引导加载程序分区。

最后,请注意,大多数计算机程序使用基于1024 = 210的幂的单位(因为程序员喜欢二进制和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的单位)。这样1TB的驱动器只有931 GiB或0.904 TiB。

评论


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

–吉尔斯'所以-不再是邪恶的'
2014年3月19日上午10:10

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

– dotancohen
2014年3月19日在10:52

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

–伊兹卡塔
2014年3月19日14:32

@illuminÉ对我而言,Solaris太高级了,我不知道它适合什么级别。

–吉尔斯'所以-不再是邪恶的'
2014年3月19日15:56

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

–StéphaneChazelas
17年2月6日在14:07

#2 楼

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




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

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

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

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

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

评论


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

–吉尔斯'所以-不再是邪恶的'
18-2-20在12:46

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

– Pedro
18年2月20日在15:24

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

–吉尔斯'所以-不再是邪恶的'
18年2月20日在16:10

#3 楼

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

du显示了累加多少的详细信息存储每个人的目录都很消耗(类似于Windows中的windirstat)。非常适合在尝试进行文件清理时查找占用空间的地方。

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

#4 楼

我将在这里说明导致dudf不同的情况。
df计算文件系统分配的块数,du使用每个文件的大小信息。
差异可能有很多原因:


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


挂载点下方的文件隐藏到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
 



稀疏文件看上去比现实。未分配的块不会由df进行计数,但表观文件大小将由du进行计数。


请注意,硬链接不会欺骗du