文件是否按顺序保存在磁盘上?


22

据我了解,“稀疏文件”是指文件可能具有“空白”,因此实际使用的数据可能小于逻辑文件的大小。

Linux文件系统如何在磁盘上保存文件?我主要对ext4感兴趣。但:

  1. 可以按顺序将文件保存在磁盘上吗?就是说,我的意思是文件的一部分位于物理地址X处,另一部分位于物理地址Y处(与X +偏移量不接近)。
  2. 我可以以某种方式控制文件顺序吗?
    我想分配一个10GB的文件。我希望它在磁盘上是连续的,而不是在不同的偏移量之间划分。
  3. 不同类型之间的行为是否有所不同?


1
也许,如果我正确地理解了您的意图,那么您将对低级API更加感兴趣,在该API中,您无需使用文件系统层即可使用存储设备。然后,您的入口点可以是dmsetup程序,即设备映射器的接口。如果您正在计划类似数据库的存储,这可能是一个不错的选择。
wvxvw

4
这是文件系统的实现细节。默认情况下,几乎所有文件系统都会执行碎片文件。仅iso9660romfs无能为力,并且需要连续存储(其中我可以列出其他内容)。
mirabilos

2
不管文件在磁盘上是否连续,除非您寻求文件的另一部分,否则数据读/写将始终是连续的。那你为什么要关心这个呢?除非碎片是影响性能的严重问题
phuclv

3
@hudac要记住的一件事是,在实践中,连续并不是全部有用。最简单的方法是闪存,在这种情况下碎片并不重要,但是在旋转的磁盘上,您仍可能无法从连续数据中受益。在旋转的磁盘上,您需要考虑访问模式以及数据的位置。如果您需要刚刚从头顶经过的扇形,则必须等待它再次完全旋转。为了获得最佳结果,您需要交错排列数据,以便在需要读取数据时将其“关闭”。增大缓存大小更容易;-)
Ukko

Answers:


41

可以按顺序将文件保存在磁盘上吗?我的意思是,文件的一部分位于物理地址X下,另一部分位于物理地址Y下(不接近X +偏移量)。

是; 这被称为文件碎片,并且并不少见,尤其是对于较大的文件。大多数文件系统或多或少按顺序分配所需的空间,但它们无法猜测未来的行为-因此,如果您向文件写入200MiB,然后再添加100MiB,则两组数据将以非零的机会可以将它们存储在磁盘的不同区域中(基本上,任何其他需要更多磁盘空间的写操作(发生在第一次写操作之后和第二次写操作之前,都可以介于两者之间))。如果文件系统快要满了,情况通常会更糟:可能没有足够大的连续空间来容纳新文件,因此必须将其碎片化。

我可以以某种方式控制文件的顺序性吗?我想分配10GB的大文件。我希望它在磁盘中是连续的,而不是在不同的偏移量之间划分。

创建文件时,您可以告诉文件系统目标大小。这将有助于文件系统最佳地存储它。许多现代文件系统使用一种称为延迟分配的技术,该技术会尽可能晚地计算新文件的磁盘布局,以最大化执行计算时可用的信息。您可以使用posix_fallocate(3)函数告诉文件系统总共应分配多少磁盘空间来帮助完成此过程。现代文件系统将尝试按顺序执行此分配。

不同类型之间的行为是否有所不同?

是的,不同的文件系统的行为不同。NILFS2等基于日志的文件系统分配存储空间的方式与Ext4等基于扩展数据块的文件系统分配方式不同,这只是变化的一个示例。


1
使用会fallocate(3)确保文件的连续性吗?还是只是暗示文件系统?我无法从手册页中完全了​​解它。
hudac '17

6
它不能确保顺序分配,这只是一个提示。但是,如果要编写10GiB文件,则一定要使用它!
斯蒂芬·基特

6
本质上,所有比FAT更复杂的文件系统-可以一直追溯到原始的伯克利UFS-将有意分解大文件并将它们分散到多个“分配组”中。这有助于他们最大程度地减少磁盘的整体碎片。有可能是一种方式来调整该如何工作的,但有你不得不从头开始重新创建文件系统,为了做到这一点很好的机会,有可能是没有办法把它彻底关闭。
zwol

2
@hudac不可能在所有情况下都保证顺序性(请参见驱动器接近满的情况),并且对于SSD的兴起来说,这比以前要重要的多(至少对于那些负担得起的人而言) )。
Muzer

1
还要注意,在某些情况下(例如RAID系统),即使有可能,连续文件的效率也较低。我认为这确实是磁盘/存储子系统控制器的目的:尽可能合理地预期地卸载存储文件的所有工作。
jamesqf

17

该命令filefrag将告诉您文件如何物理存储在设备上:

# filefrag -v /var/log/messages.1 
Filesystem type is: ef53
File size of /var/log/messages.1 is 41733 (11 blocks, blocksize 4096)
 ext logical physical expected length flags
   0       0  2130567               1 
   1       1 15907576  2130568      1 
   2       2 15910400 15907577      1 
   3       3 15902720 15910401      7 
   4      10  2838546 15902727      1 eof
/var/log/messages.1: 5 extents found

如果您一次性写入文件,我想您的文件将不会碎片化。

fallocate(1)的手册页非常清楚:

fallocate 用于将块预分配给文件。对于支持fallocate系统调用的文件系统,这可以通过分配块并将其标记为未初始化来快速完成,不需要对数据块进行IO。这比通过用零填充文件来创建文件要快得多。

从Linux Kernel v2.6.31开始,fallocatebtrfs,ext4,ocfs2和xfs文件系统支持该系统调用。

它是顺序的吗?系统将首先尝试按顺序分配块。如果不能,它将不会警告您。


什么是“ ef53”类型。我在文件中也看到了它。但是我的FS类型是ext4
hudac '17

2
EF53是ext2,ext3和ext4的“ SUPER_MAGIC”数。在内核源代码中的“ include / uapi / linux / magic.h”中查找每个文件系统的所有幻数。
Vouze

在Debian上,filefrag隐藏在中/usr/sbin。但这似乎对普通用户有效(至少在ext4上)。strace如果缺少警告会阻碍您的工作,那么了解如何为自己量度碎片可能对它的操作很有帮助。
Toby Speight

6

您提到的是稀疏文件,其他答案都没有提到它们。

大多数文件都不稀疏。创建文件的最常见方法是从头到尾全部写入。那里没有孔。

但是,您可以说“移动到1,000,000,000,000并在其中写入一个字节”。这将创建一个文件,看起来像是一个etabyte大,但实际上仅(可能)在磁盘上使用4k。这是一个稀疏文件。

您可以对同一文件多次执行此操作,从而使少量数据分散在巨大的空白中。

虽然这很有用,但有两个缺点。

首先是文件将被碎片化,这就是您所担心的。

第二个问题是,并非所有程序都能很好地处理这些文件。例如,某些备份软件将尝试备份空度,从而创建比所需容量大得多的备份,对于备份介质而言可能太大


但是,即使是非稀疏文件,在磁盘上也常常是不连续的。
Barmar '17

2

我可以以某种方式控制文件顺序吗?我想分配一个10GB的文件。我希望它在磁盘上是连续的,而不是在不同的偏移量之间划分。

至少有两种方法可以实现此目的。

  1. 使用具有大量备用空间的文件系统并预先分配空间(例如,使用特定于应用程序的数据结束标记并附加随机数据,直到文件大小达到10GB)。不能保证不会导致碎片数据。

  2. 使用原始(未煮过的)文件系统而不是ext4等。出于性能原因,DBMS有时会这样做。权衡是您需要自己进行缓存/日志记录/恢复等。

您从中获得很多收益的实例相对很少-我首先会去其他地方优化性能。


也可以看看

数据库管理系统是否通常绕过文件系统是否正确?


-1

如果这只是一次性的事情,并且文件的原始存储方式不重要,那么结果就很重要,那么您可以正常保存文件,然后运行操作系统的碎片整理程序。然后,您可以使用此答案检查文件是否为一个文件,如果不是,请重复。这是最简单的方法,无需使用命令或外部程序,但这当然不是最快的方法,因为它会整理整个磁盘的碎片。


1
“运行碎片整理程序”?有这样的程序吗?当我搜索与唯一发现aptitude search ~ddefragddrescueviewnidsTCP分段重组库。如果您不说程序被调用的内容或需要传递什么参数,那么您的回答不是很有帮助。
Toby Speight

1
@TobySpeight-是的,有一个碎片整理程序;e4defrag。
狂欢
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.