ext4文件系统
2010-12-28 13:01:05 阿炯

Ext4(第四扩展文件系统)文件系统是Linux系统下的日志文件系统,是ext3文件系统的后继版本,Linux Kernel 自 2.6.28 开始正式支持新的文件系统 ext4。在很多方面,ext4相对于ext3的进步要远超过ext3相对于ext2的进步。ext3相对于ext2的改进主要在于日志方面,但是ext4相对于ext3的的改进是更深层次的,是文件系统数据结构方面的优化。一个高效的、优秀的、可靠的和极具特点的文件系统就此诞生。Ext4官方Wiki提供了更多的介绍。

Ext4可以提供更佳的性能和可靠性,还有更为丰富的功能:
1. 与 ext3 兼容。执行若干条命令,就能从 ext3 在线迁移到 ext4,而无须重新格式化磁盘或重新安装系统。原有 ext3 数据结构照样保留,ext4 作用于新数据,当然整个文件系统因此也就获得了 ext4 所支持的更大容量。

2. 更大的文件系统和更大的文件。较之 ext3 目前所支持的最大 16TB 文件系统和最大 2TB 文件,ext4 分别支持 1EB(1,048,576TB,1EB=1024PB,1PB=1024TB)的文件系统,以及 16TB 的文件。

1EB=1024PB=1024*1024TB=1024*1024*1024GB

上述这个特性是由于ext4采用了48位寻址。为什么不是64位呢?因为就目前的开发进展来看,实现64位寻址存在一些技术限制,但是ext4已经在考虑这个问题了,在不久的将来ext将实现完全的64位支持。

3. 无限数量的子目录。ext3 目前只支持 32,000 个子目录,而 ext4 支持无限数量的子目录。

4. extents。ext3 采用间接块映射,当操作大文件时,效率极其低下。比如一个 100MB 大小的文件,在 ext3 中要建立 25,600 个数据块(每个数据块大小为 4KB)的映射表。而 ext4 引入了现代文件系统中流行的 extents 概念,每个 extent 为一组连续的数据块,上述文件则表示为“该文件数据保存在接下来的 25,600 个数据块中”,提高了不少效率。

传统的类UNIX文件系统,比如ext3,都是使用一个间接数据块映射表来记录每一个数据块的分配情况的。但是这种机制对于超大文件的存储是有缺陷的,特别是当对超大文件进行删除和截断操作时。映射表会对每一个数据块进行记录,而一个超大文件将占有很多的数据块,因此造成映射表将变得无比臃肿,难于维护。ext4引入了一个新的概念,叫做“extents”。一个extents是一个地址连续的数据块的集合。比如一个100MB的文件将被分配给一个单独的extents,这样就不用像ext3那样新增25600个数据块的记录(一个数据块是4KB)。而超大型文件会被分解在多个extents里。extents的实现提高了文件系统的性能,减少了文件碎片。

5. 多块分配。当写入数据到 ext3 文件系统中时,ext3 的数据块分配器每次只能分配一个 4KB 的块,写一个 100MB 文件就要调用 25,600 次数据块分配器,而 ext4 的多块分配器“multiblock allocator”(mballoc)支持一次调用分配多个数据块。

在ext3中,“将新的数据写入磁盘的哪些空闲块”是由块分配器来控制的。但是ext3的块分配器存在一定缺陷,那就是它一次只能够分配一个数据块(4KB),这就意味着系统需要向磁盘中写入100MB的数据,那么需要调用块分配器25600次,而且由于块分配器无法获知总的分配块数,所以也无法对分配空间和分配位置进行优化。在ext4中,使用了“多块分配器”,即一次调用可以分配多个数据块,这种机制提高了系统的性能,而且使得分配器有了充足的优化空间。

6. 延迟分配。ext3 的数据块分配策略是尽快分配,而 ext4 和其它现代文件操作系统的策略是尽可能地延迟分配,直到文件在 cache 中写完才开始分配数据块并写入磁盘,这样就能优化整个文件的数据块分配,与前两种特性搭配起来可以显著提升性能。

延迟分配(Delayed allocation)是一项仅仅少数现代文件系统才具有的优秀特性,比如XFS、ZFS、btrfs(betterFS)以及Reiser4。它能够尽可能的积累更多的数据块再分配出去,相对比传统的文件系统则会尽快的将数据块分配出去,如ext3,reiser3等。这项特性会和extents特性以及多块分配特性相结合,使得磁盘IO性能得到显著提高。

7. 快速 fsck。以前执行 fsck 第一步就会很慢,因为它要检查所有的 inode,现在 ext4 给每个组的 inode 表中都添加了一份未使用 inode 的列表,今后 fsck ext4 文件系统就可以跳过它们而只去检查那些在用的 inode 了。

在ext3中,Fsck本身是个速度很慢的操作,因为它要检查文件系统里的每一个“i节点”。但ext4会维护一个未使用的"i节点"表,在进行fsck操作时,会跳过表中节点,只检查正在使用中的i节点。这种机制使得fsck的效率提高为原有ext3文件系统的2到20倍。不过你要注意到一点,那就是这个未使用的i节点表是由fsck来维护的,而不是由ext4,因此你必须要首先运行一次fsck来生成,这样,在下次再运行fsck时才可以享受提速。(虽然表是由fsck来维护的,但你还是需要从ext3升级到ext4才能够享受这项功能)

8. 日志校验。日志是最常用的部分,也极易导致磁盘硬件故障,而从损坏的日志中恢复数据会导致更多的数据损坏。ext4 的日志校验功能可以很方便地判断日志数据是否损坏,而且它将 ext3 的两阶段日志机制合并成一个阶段,在增加安全性的同时提高了性能。

日志要算是磁盘中最常用的部分了,也是最容易使硬盘出问题的机制之一。如果不幸使用一个已经崩溃的日志来恢复系统的话,将导致更大规模的系统崩溃。ext4提供校验日志数据的功能,可以查看其潜在错误。且ext4还会将ext3日志机制中的“两阶段提交”动作合并为一个步骤,这种改进将使文件系统的操作性能提升20%。这就是ext4在日志机制方面对可靠度和性能的双重提升。

9. "无日志"(No Journaling)模式。日志总归有一些开销,ext4 允许关闭日志,以便某些有特殊需求的用户可以借此提升性能。

10. 在线碎片整理。尽管延迟分配、多块分配和 extents 能有效减少文件系统碎片,但碎片还是不可避免会产生。ext4 支持在线碎片整理,并将提供 e4defrag 工具进行个别文件或整个文件系统的碎片整理。这个特性没有包括在内核版本2.6.28之中,但是它很有可能会在下一个版本中引入。

虽然extents、多块分配和延迟分配都有助于减少磁盘碎片,但是磁盘碎片仍然会产生。举例来说:你在一个目录下建立了三个文件 (f1,f2,f3),它们被按序写入到连续的一段内存之中。然而几天之后,你想要更新文件f2,也就是位于这段连续内存的中间那一段的那个文件。我要向这个文件中增加一些字符。很明显,在这段连续内存之中已经没有地方放下增加的这些字符,这别无选择,只能将这个f2文件移动到一个能容纳下的新的连续内存之中。这导致了f2文件和f1、f3文件离的非常远,读取也相对缓慢了。这就产生了磁盘碎片了。还有可引导文件应该被放在连续的内存之中,但是磁盘整理机制并不知道哪些文件是可引导文件。

11. inode 相关特性。ext4 支持更大的 inode,较之 ext3 默认的 inode 大小 128 字节,ext4 为了在 inode 中容纳更多的扩展属性(如纳秒时间戳或 inode 版本),默认 inode 大小为 256 字节。ext4 还支持快速扩展属性(fast extended attributes)和 inode 保留(inodes reservation)。

更大的i结点:ext3支持自定义i结点大小,但是默认的i结点大小是128字节,ext4将默认大小提升到256字节。增加的空间用来存储更多的结点信息,这样有利于提升磁盘性能。

i结点预留机制:当新建一个目录时,若干i结点会被预留下来,等新的文件在此目录中创建时,这些预留的i结点就可以立即被使用,文件的建立和删除将变得更加高效。

毫微秒级的时间戳:在ext3中,时间精度是秒。在ext4中,时间精度提升到了毫微秒。

12. 持久预分配(Persistent preallocation)。P2P 软件为了保证下载文件有足够的空间存放,常常会预先创建一个与所下载文件大小相同的空文件,以免未来的数小时或数天之内磁盘空间不足导致下载失败。ext4 在文件系统层面实现了持久预分配并提供相应的 API(libc 中的 posix_fallocate()),比应用软件自己实现更有效率。

这个特性,已经出现在了ext3的最后几个内核版本中,并且也可以由glibc在不支持此功能的文件系统中模拟产生,允许应用程序去预分配磁盘空间。应用程序告知文件系统给预留出一定的空间,文件系统会据此预分配必要的数据块,但是这些数据块将会是空的,直到应用程序向里面写入数据为止。这个机制会常常在P2P应用程序中用到,因为P2P应用程序下载文件常常需要几天的时间。这种机制也防止了磁盘碎片的产生,因为文件系统会一次性分配尽可能连续的数据块给应用程序。这种机制对于实时系统非常重要,因为一旦没有这种机制,可能将会导致在一次重要操作的半截,磁盘空间已满。这项特性是通过调用posix_fallocate()来实现的。

13. 默认启用 barrier。磁盘上配有内部缓存,以便重新调整批量数据的写操作顺序,优化写入性能,因此文件系统必须在日志数据写入磁盘之后才能写 commit 记录,若 commit 记录写入在先,而日志有可能损坏,那么就会影响数据完整性。ext4 默认启用 barrier,只有当 barrier 之前的数据全部写入磁盘,才能写 barrier 之后的数据(可通过 "mount -o barrier=0" 命令禁用该特性)。

注:目前的ext4文件系统是第一个稳定版本,整个的开发进度和发布计划都被放缓了,就是为了保证用户可以享受到“和使用ext3同等级”的稳定。


Ext4维护

一)、性能选项

可以使用 tune2fs 程序调优 ext4 文件系统,与调优 ext2 或 ext3 文件系统的方式一样。目前, tune2fs 不提供任何特定于 ext4 的选项,但是可以使用标准的 -O 参数设置 ext4 选项,如 extent。

当把文件系统挂载为 ext4 时,内核开始使用特定于文件系统的功能,如 extent。这样做的结果是不能再把文件系统挂载为 ext3 文件系统,至少会变得非常困难。尽管把 ext3 文件系统挂载为 ext4 能够实现特定于 ext4 的功能,挂载本身并不把旧数据结构转换为新的格式。例如,现有文件保持块状方式分配,而不是使用 extent 进行分配。因此,旧文件没有从新功能获得好处。然而,ext4 的开发人员已经考虑到这种情况并且提供了一种解决办法:可以使用(正处于 试验阶段的)e4defrag 工具转换分配方式来利用 extent 功能。

二)、常规维护

可以使用标准的 e2fsprogs 工具来维护 ext4 文件系统,例如使用 tune2fs 在创建文件系统之后调整选项,使用 fsck.ext4 执行文件系统检查等等。这些程序在 ext4 与 ext3 之间没有很大的差别。但如前面提到的一样,ext4 包含一些能够提升 fsck 性能的增强功能。

除了这些工具以外,有一个新工具特别值得注意:e4defrag。该程序能够对已挂载的 ext4 文件系统进行磁盘碎片整理。这能够提高性能,尤其是文件系统空间快要用完的时候。同时,这也有利于将 ext2/3 样式的分配转换为基于 extent 的 ext4 样式的分配,因此能够提高曾经作为 ext3 文件系统的文件系统的性能。不幸的是,e4defrag 还不是标准的 e2fsprogs 包的一部分,因此需要单独下载。

三)、释放ext4的保留空间

在较大的分区或是不重要的分区上这种设置会占据过多不必要的空间, 利用mke2fs的-m reserved-percentage选项可以调整这个设置来获得更多的磁盘空间且不影响性能。而在创建了文件系统之后,用户可以用tune2fs来修 改这个设置。

tune2fs -m 1 /dev/sdx
1就是保留1%的空间。不推荐0,因为如果是root盘还是有点保留一点好。一般留100M差不多了:
tune2fs -r 25600 /dev/sdx
100M=(25600*4Kb)/1024

保留256MB:
tune2fs -r 65536 /dev/sdx

命令执行完毕立即生效,无需重启。如果是数据盘默认的5%肯定是浪费了。2TB硬盘,格式化之后5%的保留空间是93.3G,不过我的数据盘不用EXT格式。

四)、jbd2引起的高IO问题

多发于CentOS6 x64系统上,内核版本在2.6.32。jbd系ext3+文件系统的日志功能,jbd2对应的是ext4文件系统版本。

The Journaling Block Device (JBD) provides a filesystem-independent interface for filesystem journaling. ext3-4 and OCFS2 are known to use JBD. OCFS2 starting from Linux 2.6.28 and ext4 use a fork of JBD called JBD2.

使用ps来检查是否存在 jbd2 进程,dumpe2fs检查文件系统的功能(下为CentOS7 x64的输出)
dumpe2fs /dev/vdb1 | grep has_journal
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem features:    has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize

看是否存在 has_journal。另外在使用 iotop 工具指令查看时,jbd2/dm-0-3进程占用了大部分的IO使用率。

可能的原因

1.磁盘满

2.系统 bug
    已知 bug 号:Bug 39072 - jbd2 writes on disk every few seconds
    
3.即使没有以上问题。在 ext4 上有一个新加入的参数 barrier,是用来保证文件系统的完整性的。
    3.1.[Barrier解释]()。
    3.2.这个值默认是1,即是打开状态。在这个状态下,打开 jbd2 也是会导致性能下降的,这个玩意的设计逻辑就是为了损失掉性能保证文件完整性。
    3.3.这是个选择题,要么不用它,要么性能差。但是这个功能不能和设备映射器同时使用,也即是,如果你使用了逻辑卷、软RAID、多路径磁盘,则这个值不生效。

解决办法

方案1
在分区挂载前关闭日志功能
tune2fs -o journal_data_writeback /dev/vdb1
tune2fs -O "^has_journal" /dev/vdb1
e2fscj -f /dev/vdb1

方案2
如果是 bug 的话,可以用这种方式解决。如果是不是 bug,可以考虑升级系统内核,所以要先判断下引起问题的原因再选择解决方案。

方案3
禁用 Barrier 的同时修改 commit 的值。这个方式可以解决 barrier 引起的性能下降,但是解决不了系统 bug 的问题。

修改 commit 值,降低文件系统提交次数或者禁用 barrier 特性;建议文件系统参数为:
defaults,noatime,nodiratime,barrier 0,data writeback,commit 60

然后重新挂载
mount -o remount,commit 60 /freeoa

其中 barrier=0 是禁用 barrier 特性,commit=60 是减少提交次数。减少提交次数只能缓解。

方案4
如果不是 bug,并且不想禁用 barrier 时,用调优应用读写的方式缓解。想办法降低IO,缓解其压力。比如说在 mysql 中把 syncbinlog 加大,同时将innodbflushlogattrxcommit 增加。或加大内存使用或合并IO操作等。

在kernel tracker里看到的问题信息最早是2011年,如果如果是用的老版本,建议先做升级。如果没有升级条件,只能用上面的关闭日志功能的解决方案。可能系ext4使用 extent 取代了传统的 block 映射方式的方式引入的,其中有数字的溢出导致。

Linux 文件系统 EXT4 的前世今生

下文的译文转自开源中国,感谢翻译者们。英文原文:An Introduction to Linux's EXT4 Filesystem

在先前关于Linux文件系统的文章中,我写了一份说明书去介绍Linux文件系统,里面有一些高级的概念,比如说,一切都是文件。我很想去深入地讨论更多EXT文件系统的特性的信息。所以,首先让我们来回答这个问题:什么是文件系统?一个文件系统应该遵循以下特点:
1.数据存储:文件系统主要的功能是结构化存储和取回数据。

2.命名空间:提供一套命名和组织的方法,就是命名和结构化数据的规则。

3.安全模型:一种访问控制的策略。

4.API:系统操控文件系统对象的函数,就像操作文件夹和文件一样。

5.实现:一个实现以上功能的软件。

这篇文章集中与上面清单的第一项,还有探究元数据结构---在EXT文件系统中提供数据存储的逻辑框架。

EXT文件系统历史

虽然是为Linux编写的,但EXT文件系统起源于Minix操作系统,而Minix文件系统早在1987年首次发布,比Linux还早五年就已经发布了。如果=查看EXT文件系统家族从其Minix根开始的历史和技术演变,就会更容易理解EXT4文件系统。

Minix

当编写原始Linux内核,Linus Torvalds需要一个文件系统,但是不想开发它。因此他简单的使用了Minix文件系统,这是 Andrew S. Tanenbaum开发的,而且是Tanenbaum 的Minix操作系统的一部分。Minix是类Unix操作系统,为教育使用而开发。它的代码开放使用,而且合理的授权给Torvalds,允许他将它用于Linux的初代版本。Minix结构如下,其中大部分位于文件系统生成的分区中:
引导扇区(boot sector)安装于硬盘的第一个扇区。引导块(boot block)包含一个非常小的引导记录和一个分区表。

每一个分区中的第一个块是超级块(superblock),它包含了定义其他文件系统结构的元数据,并将它们定位在分配给分区的物理磁盘上。

节点位图块(inode bitmap block),它确定了哪个节点在使用以及哪个节点是空闲的。

节点(inodes),它们在磁盘上有它们自己的空间。每个节点包含了一个文件的信息,包括数据块的位置,即文件所属的区域。

区域位图(zone bitmap)跟踪记录数据区域的使用和释放。

数据区域(data zone),数据实际上存储的位置。

对于位图的两个类型来说,一个bit代表了一个特有的数据区域或者一个特有的节点。如果这个bit是0,这个区域或者节点是空闲的而且可供使用,但是如果这个bit是1,这个数据区域或者节点是在使用中的。

节点是什么?它是索引节点(index-node)的缩写,一个节点是在磁盘上的一个256字节的块,而且它存储文件相关的数据。这些数据包括文件的大小;文件的用户和所属组的用户ID;文件模式(即访问权限);以及三个时间戳具体说明了时间,包括:文件最后访问时间,最后修改时间,以及节点中的数据最后修改时间。

节点也包含了:指向硬盘上文件数据所在的位置。在Minix和EXT1-3文件系统中,它是一个数据区域和块的列表。Minix文件系统节点支持9个数据块,7个直接指针和2个间接指针。如果你想了解的更多,这有一个很好的PDF详细描述了Minix文件系统结构,以及在Wikipedia上对节点指针结构的快速概述。

EXT

最初的EXT文件系统(Extended)由Rémy Card编写,并于1992年与Linux一起发布,以规避Minix文件系统的一些大小限制。其中主要的结构变化是基于Unix文件系统(UFS)的文件系统元数据,该结构也被称为伯克利快速文件系统(FFS)。我发现很少有关于此EXT文件系统的可考究的发布信息,显然是因为它存在重大问题,并很快被EXT2文件系统所取代。1992 年的 ext 使用在 Linux 内核中的新虚拟文件系统(VFS)抽象层。与之前的 MINIX 文件系统不同的是,ext 可以处理高达 2 GB 存储空间并处理 255 个字符的文件名。但 ext 并没有长时间占统治地位,主要是由于它原始的时间戳(每个文件仅有一个时间戳,而不是今天我们所熟悉的有 inode、最近文件访问时间和最新文件修改时间的时间戳)。

EXT2

EXT2文件系统非常成功。它在Linux发行版中被使用了很多年,并且它是我在1997年左右开始使用Red Hat Linux 5.0时遇到的第一个文件系统。EXT2文件系统与EXT文件系统具有基本相同的元数据结构,但EXT2更具前瞻性,因为在元数据结构之间保留大量磁盘空间以供未来使用。

像Minix一样,EXT2在其安装的硬盘的第一个扇区中有一个引导扇区,其中包括一个非常小的引导记录和一个分区表。在引导扇区后面有一些预留空间,它跨越引导记录和硬盘上通常位于下一个柱面边界上的第一个分区之间的空间。 GRUB2(可能还有GRUB1)使用这个空间作为其启动代码的一部分。

每个EXT2分区中的空间被划分为多个柱面组,可以更加精细地管理数据空间。根据我的经验,组大小通常约为8MB。下面的图1显示了柱面组的基本结构。柱面中的数据分配单元是块,其大小通常为4K。


图1:EXT文件系统中柱面组的结构

柱面组中的第一个块是一个超级块,它包含定义其他文件系统结构并将其定位在物理磁盘上的元数据。分区中的一些附加组将具有备份超级块,但不是全部。损坏的超级块可以使用dd等磁盘实用程序将备份超级块的内容复制到主超级块。它并不经常发生,但是多年前曾经有一个受损的超级块,我可以使用其中一个备份超级块来恢复其内容。 幸运的是,我已经预见到并使用dumpe2fs命令转储我系统上分区的描述符信息。下面是dumpe2fs命令的部分输出。它显示了超级块中包含的元数据,以及关于文件系统中前两个柱面组的数据。

# dumpe2fs /dev/sda1
Filesystem volume name:   boot
Last mounted on:          /boot
Filesystem UUID:          79fc5ed8-5bbc-4dfe-8359-b7b36be63bd3
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir nlink extra_isize
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              122160
Block count:              488192
Reserved block count:     24409
Free blocks:              376512
Free inodes:              121690
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Reserved GDT blocks:      238
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8144
Inode blocks per group:   509
Flex block group size:    16
Filesystem created:       Tue Feb  7 09:33:34 2017
Last mount time:          Sat Apr 29 21:42:01 2017
Last write time:          Sat Apr 29 21:42:01 2017
Mount count:              25
Maximum mount count:      -1
Last checked:             Tue Feb  7 09:33:34 2017
Check interval:           0 (<none>)
Lifetime writes:          594 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     32
Desired extra isize:      32
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      c780bac9-d4bf-4f35-b695-0fe35e8d2d60
Journal backup:           inode blocks
Journal features:         journal_64bit
Journal size:             32M
Journal length:           8192
Journal sequence:         0x00000213
Journal start:            0

Group 0: (Blocks 0-32767)
 Primary superblock at 0, Group descriptors at 1-1
 Reserved GDT blocks at 2-239
 Block bitmap at 240 (+240)
 Inode bitmap at 255 (+255)
 Inode table at 270-778 (+270)
 24839 free blocks, 7676 free inodes, 16 directories
 Free blocks: 7929-32767
 Free inodes: 440, 470-8144
Group 1: (Blocks 32768-65535)
 Backup superblock at 32768, Group descriptors at 32769-32769
 Reserved GDT blocks at 32770-33007
 Block bitmap at 241 (bg #0 + 241)
 Inode bitmap at 256 (bg #0 + 256)
 Inode table at 779-1287 (bg #0 + 779)
 8668 free blocks, 8142 free inodes, 2 directories
 Free blocks: 33008-33283, 33332-33791, 33974-33975, 34023-34092, 34094-34104, 34526-34687, 34706-34723, 34817-35374, 35421-35844, 35935-36355, 36357-36863, 38912-39935, 39940-40570, 42620-42623, 42655, 42674-42687, 42721-42751, 42798-42815, 42847, 42875-42879, 42918-42943, 42975, 43000-43007, 43519, 43559-44031, 44042-44543, 44545-45055, 45116-45567, 45601-45631, 45658-45663, 45689-45695, 45736-45759, 45802-45823, 45857-45887, 45919, 45950-45951, 45972-45983, 46014-46015, 46057-46079, 46112-46591, 46921-47103, 49152-49395, 50027-50355, 52237-52255, 52285-52287, 52323-52351, 52383, 52450-52479, 52518-52543, 52584-52607, 52652-52671, 52734-52735, 52743-53247
 Free inodes: 8147-16288
Group 2: (Blocks 65536-98303)
 Block bitmap at 242 (bg #0 + 242)
 Inode bitmap at 257 (bg #0 + 257)
 Inode table at 1288-1796 (bg #0 + 1288)
 6326 free blocks, 8144 free inodes, 0 directories
 Free blocks: 67042-67583, 72201-72994, 80185-80349, 81191-81919, 90112-94207
 Free inodes: 16289-24432
Group 3: (Blocks 98304-131071)

每个柱面组都有自己的inode位图,该位图用于确定使用哪些inode,以及该组中哪些是空闲的。inode在每个组中都有自己的空间。每个inode都包含有关一个文件的信息,包括属于该文件的数据块的位置。块位图跟踪文件系统中使用和释放的数据块。注意,上面显示的输出中有大量关于文件系统的数据。在很大的文件系统中,组数据可以长达数百页。组元数据包括组中所有空闲数据块的列表。EXT文件系统实现了保证文件碎片最小化的数据分配策略,减少磁盘碎片化可改善文件系统的性能。这些策略将在下文的EXT4部分中进行介绍。

在某些情况下,我曾遇到的EXT2文件系统的最大问题是在崩溃后可能需要几个小时才能恢复,因为fsck(file system check)程序需要很长时间才能找到并纠正文件系统中的任何不一致。它曾在我的一台计算机上花费了28个小时的时间,以实现在发生崩溃到重新启动时完全恢复磁盘 -并且这是在磁盘大小为数百兆字节下测试的结果。

EXT3

EXT3文件系统的唯一目标是克服fsck程序需要大量时间来完全恢复因文件更新操作期间发生的不正确关闭而损坏的磁盘结构的问题。EXT文件系统的唯一增加了journal,它预先记录了将对文件系统执行的改动。磁盘结构的其余部分和EXT2中是相同的。

EXT3中的journal并不是直接将数据写入磁盘的数据区域,而是将文件数据及其元数据写入到磁盘上的指定区域。一旦数据安全地存储在硬盘上,它就可以合并到目标文件或附加到目标文件中,而这几乎不会丢失数据。由于该数据被提交到磁盘的数据区域,因此需更新journal以便在发生系统故障时文件系统保持一致状态,然后该journal中的所有数据都被提交。在下次启动时,将检查文件系统是否存在不一致性,然后将journal中剩余的数据提交到磁盘的数据区域以完成对目标文件的更新。

日志化确实会降低数据写入性能,但journal提供了三种选项可供用户在性能,数据完整性和安全性之间进行选择。我的个人偏好是安全性,因为我的环境不需要繁重的磁盘写入操作。日志函数最多可以减少在检查硬盘驱动发现不一致性所需的时间:从几小时(甚至几天)到几分钟不等。多年来,我遇到了很多导致系统崩溃的问题。个中细节可以填满另一篇文章,但足以证实大多数是自我原因造成的,就像踢掉电源插头一样。幸运的是,EXT日志化文件系统已将启动恢复时间缩短到两三分钟。另外,自从我开始使用带日志功能的EXT3以来,我从来没有遇到丢失数据的问题了。

EXT3的日志功能可以关闭,然后作为EXT2文件系统运行。日志功能本身仍然存在,它是空的并且是未使用的。只需使用mount命令重新挂载分区,使用type参数指定EXT2。您可以在命令行中执行此操作,这取决于您使用的是哪个文件系统,但是您可以更改/etc/fstab文件中的类型说明符,然后重新启动。我强烈建议不要将EXT3文件系统作为EXT2使用,因为可能会丢失数据并延长恢复时间。现有的EXT2文件系统可以通过使用以下命令添加日志来升级到EXT3:
tune2fs -j /dev/sda1

其中/dev/sda1是驱动器和分区标识符。确保在/etc/fstab中更改文件类型说明符,并重新启动分区或重新启动系统以使更改生效。

EXT4

EXT4文件系统主要改善了性能,可靠性和容量。为了提升可靠性,添加了元数据和日志校验和。为了完成各种各样的关键任务的需求,文件系统时间戳将时间间隔精确到了纳秒。时间戳字段的两个高位bit将2038年问题延续到了2446年——至少为EXT4文件系统延续了。

在EXT4中,数据分配从固定块变成了扩展块。一个扩展块通过它在硬盘上的起始和结束位置来描述。这使得在一个单一节点指针条目中描述非常长的物理连续文件成为可能,它可以显著减少大文件中的描述所有数据的位置的所需指针的数量。为了进一步减少碎片化,其他分配策略已经在EXT4中实现。

EXT4通过在磁盘上分散新创建的文件来减少碎片化,因此他们不会像早期的PC文件系统,聚集在磁盘的起始位置。文件分配算法尝试尽量将文件均匀的覆盖到柱面组,而且当不得不产生碎片时,尽可能地将间断文件范围靠近同一个文件的其他碎片,来尽可能压缩磁头寻找和旋转等待时间。当一个新文件创建的时候或者当一个已有文件扩大的时候,附加策略用于预分配额外磁盘空间。它有助于保证扩大文件不会导致它直接变为碎片。新文件不会直接分配在已存在文件的后面,这也阻止了已存在文件的碎片化。

除了数据在磁盘的具体位置,EXT4使用一些功能策略,例如延迟分配,允许文件系统在分配空间之前先收集到要写到磁盘的所有数据。这可以提高数据空间连续的概率。之前的EXT文件系统,例如EXT2和EXT3,可以挂载EXT4,来提升一些次要性能。不幸的是,它要求关掉一些EXT4的重要的新特性,因此我不建议这种做法。从Fedora 14开始,EXT4已经是Fedora的默认文件系统。使用在Fedroa文档描述的过程,一个EXT3文件系统可以升级到EXT4,然而由于剩余的EXT3元数据结构,它的性能仍然会受到影响。从EXT3升级到EXT4最好的方法是备份所有的目标文件系统分区的数据,使用mkfs命令将一个空的EXT4文件系统写到分区,然后从备份恢复所有数据。

节点(Inode)

在之前描述过,节点是一个EXT文件系统的元数据的关键要素。图2展示了节点和存储在硬盘上的数据之间的关系。这个示意图是目录和单一文件的节点,在这种情况下,可能是高度碎片化文件的节点。EXT文件系统为减少碎片化而积极努力,因此你不会看到有很多间接数据块或者数据区的文件。事实上,就像你将在下面看到的,碎片化在EXT文件系统中非常少见,因此大多节点会只用一个或者两个直接数据指针而且不使用间接指针。


图2:节点存储了关于每个文件的信息和EXT文件系统对所有属于它的数据的定位。

节点不包含文件的名称。通过目录项(directory entry)来访问文件,它自己就是文件的名称而且包含指向此节点的指针。指针的值是节点号。每个文件系统中的节点都有一个唯一的ID号,但是在同一个电脑(甚至同一个硬盘)的其他文件系统中的节点可以有相同的节点号。这会对硬连接产生一些后果,这方面内容超出了本文的范围。

节点包含了文件的元数据,包括它的类型和权限以及它的大小。节点也包含了15个指针的空间,来描述柱面组中数据部分中的数据块或数据区的位置和长度。12个指针提供了数据区的直接访问,而且对处理大部分文件都是足够的。然而,对于有大量碎片的文件,它可能必须需要一些额外的空间,以间接节点的形式描述。从技术上来讲,它们不是真正的节点,因此为了方便我使用短语“间接节点(node)”。

间接节点是文件系统中一个常规的数据块,只用于描述数据而且不用存储元数据,因此可以支持超过15个指针。例如,一个大小为4K的块可以支持512个4字节间接节点,允许一个单一文件包含12(直接)+512(间接)=524个区。同样也支持双重或三重间接节点,但是我们一般不太可能遇到需要这么多区的文件。

数据碎片

对于许多陈旧的PC文件系统(诸如FAT(及其所有变体)和NTFS),碎片化一直是导致磁盘性能下降的主要问题。碎片整理本身就成为一个行业,囊括不同品牌的碎片整理软件,其作用从非常有效到表现平平。

Linux扩展文件系统使用的数据分配策略,有助于最大限度地减少硬盘驱动器上文件的碎片,并在碎片发生时减少碎片效应。你可以在EXT文件系统上使用fsck命令来检查整个文件系统的碎片。以下示例检查我的主工作站的主目录,该目录仅有1.5%碎片化。请务必使用-n参数,因为它可以防止fsck对所扫描的文件系统执行任何操作。

fsck -fn /dev/mapper/vg_01-home

我曾经进行过一些理论上的计算,以确定磁盘碎片整理是否会导致性能显着提高。虽然我确实做了一些假定,但我使用的磁盘性能数据来自新的300GB,Western Digital硬盘,具有2.0ms的磁轨间寻址时间。本例中的文件数量是我在计算当天存在于该文件系统中的实际数量。我确实假定每天都会触发相当多的碎片文件(20%)。


表1: 碎片化对磁盘性能的理论上的影响

我已经做了两次测算,每天总的附加寻址时间,一次是基于磁轨间寻址时间,这是由于EXT文件分配策略而导致大多数文件更可能出现的情况,另一种是平均寻址时间,我假定这会触发相当于最坏的情形。

从表1可以看出,对于具有相当性能的硬盘驱动器的现代EXT文件系统来说,碎片化影响最小;对绝大多数应用程序来说可以忽略不计。你可以将实际环境中的数据插入到你自己的类似电子表格中,以得到你对性能影响的预期。这种计算方式很可能不会代表实际性能,但它可以提供对碎片话及其对系统的理论上的影响的一些洞察力。大部分分区大约1.5%或1.6%碎片化,我确实有一个3.3%碎片化的分区,但这是一个大的,128GB的文件系统,拥有少于100个非常大的ISO映像文件;多年来,我不得不多次扩展此分区,因为它太满了。

这并不是说某些应用程序环境不需要更少的碎片文件的保证。EXT文件系统可以由知识渊博的管理员进行调整,他们可以调整参数以补偿特定的工作负载类型。这可以在文件系统被创建时或之后使用tune2fs命令来完成。应对每次调优改动的结果进行测试,细致地记录并进行分析,以确保对目标环境达到最佳性能。在最差的情况下,如果性能无法提升到所需的水平,则可能有更适合特定工作负载的其他文件系统类型。请记住,在单个主机系统上混用文件系统类型以匹配每个文件系统上的负载是很常见的。

由于在大多数EXT文件系统中碎片数量很少,因此不需要进行碎片整理。无论如何,EXT文件系统都没有安全的碎片整理工具。目前有几个工具可以让你检查单个文件的碎片状况或文件系统中剩余空闲空间的碎片化状态。有一个工具,e4defrag,它将在可用空间允许的前提下对文件、目录或文件系统进行尽可能地碎片化整理。顾名思义,它只适用于EXT4文件系统中的文件,并且存在一些局限性。

如果有必要对EXT文件系统执行完全的碎片整理,则仅有一种方法可以可靠地工作。你必须移动文件系统中的所有文件以进行碎片整理,以确保在将文件安全复制到其他位置后将其删除。如果可能的话,你可以增加文件系统的大小来辅助减少将来的碎片产生。然后将文件复制回目标文件系统。即使这样做并不能保证所有的文件都会被完全去碎片化。

结论

20多年来,EXT文件系统一直是许多Linux发行版的默认文件系统。它们需要少量的维护就能提供稳定性、高容量、可靠性和性能。我尝试过其他文件系统,但总是回到EXT。毫无疑问,EXT4文件系统应该用于大多数Linux系统,除非有令人信服的理由去使用另一个文件系统。

关于作者

David Both。他居住在北卡罗来纳州的Raleigh,是Linux和开源的支持者。他在IT行业工作了四十多年,并在IBM教授OS/2了二十多年。在IBM工作期间,他在1981年为最初的IBM PC编写了第一期培训课程。他曾为红帽教授RHCE课程,并曾在MCI Worldcom,思科和北卡罗莱纳州工作。他在Linux和开源软件方面工作了近20年。David为OS/2杂志,Linux杂志,Linux周刊和OpenSource.com撰写了文章。他与思科同事合作撰写的文章“Complete Kickstart”在2008年Linux杂志十大最佳系统管理文章排行榜中名列第九。

在 2006 年发表的 ext4,于两年后在 2.6.28 内核版本中被加入到了 Linux 主线。ext4 特地设计为尽可能地向后兼容 ext3,这不仅允许 ext3 文件系统原地升级到 ext4;也允许 ext4 驱动程序以 ext3 模式自动挂载 ext3 文件系统,因此使它无需单独维护两个代码库。

ext3 文件系统使用 32 位寻址,这限制它仅支持 2 TiB 文件大小和 16 TiB 文件系统系统大小(这是假设在块大小为 4 KiB 的情况下,一些 ext3 文件系统使用更小的块大小,因此对其进一步被限制)。ext4 使用 48 位的内部寻址,理论上可以在文件系统上分配高达 16 TiB 大小的文件,其中文件系统大小最高可达 1000000 TiB(1 EiB)。在早期 ext4 的实现中有些用户空间的程序仍然将其限制为最大大小为 16 TiB 的文件系统,但截至 2011 年,e2fsprogs 已经直接支持大于 16 TiB 大小的 ext4 文件系统。例如,红帽企业 Linux 在其合同上仅支持最高 50 TiB 的 ext4 文件系统,并建议 ext4 卷不超过 100 TiB。

分配方式改进


ext4 在将存储块写入磁盘之前对存储块的分配方式进行了大量改进,这可以显著提高读写性能。

区段
区段(extent)是一系列连续的物理块 (最多达 128 MiB,假设块大小为 4 KiB),可以一次性保留和寻址。使用区段可以减少给定文件所需的 inode 数量,并显著减少碎片并提高写入大文件时的性能。

多块分配
ext3 为每一个新分配的块调用一次块分配器。当多个写入同时打开分配器时,很容易导致严重的碎片。然而,ext4 使用延迟分配,这允许它合并写入并更好地决定如何为尚未提交的写入分配块。

持久的预分配
在为文件预分配磁盘空间时,大部分文件系统必须在创建时将零写入该文件的块中。ext4 允许替代使用 fallocate(),它保证了空间的可用性(并试图为它找到连续的空间),而不需要先写入它。这显著提高了写入和将来读取流和数据库应用程序的写入数据的性能。

延迟分配
这是一个耐人寻味而有争议性的功能。延迟分配允许 ext4 等待分配将写入数据的实际块,直到它准备好将数据提交到磁盘(相比之下,即使数据仍然在往写入缓存中写入,ext3 也会立即分配块)。当缓存中的数据累积时,延迟分配块允许文件系统对如何分配块做出更好的选择,降低碎片(写入,以及稍后的读)并显著提升性能。然而不幸的是,它增加了还没有专门调用 fsync() 方法(当程序员想确保数据完全刷新到磁盘时)的程序的数据丢失的可能性。

假设一个程序完全重写了一个文件:
fd=open("file", O_TRUNC); write(fd, data); close(fd);

使用旧的文件系统,close(fd); 足以保证 file 中的内容刷新到磁盘。即使严格来说,写不是事务性的,但如果文件关闭后发生崩溃,则丢失数据的风险很小。

如果写入不成功(由于程序上的错误、磁盘上的错误、断电等),文件的原始版本和较新版本都可能丢失数据或损坏。如果其它进程在写入文件时访问文件,则会看到损坏的版本。如果其它进程打开文件并且不希望其内容发生更改 -- 例如,映射到多个正在运行的程序的共享库。这些进程可能会崩溃。

为了避免这些问题,一些程序员完全避免使用 O_TRUNC。相反,他们可能会写入一个新文件,关闭它,然后将其重命名为旧文件名:
fd=open("newfile"); write(fd, data); close(fd); rename("newfile", "file");

在没有延迟分配的文件系统下,这足以避免上面列出的潜在的损坏和崩溃问题:因为 rename() 是原子操作,所以它不会被崩溃中断;并且运行的程序将继续引用旧的文件。现在 file 的未链接版本只要有一个打开的文件文件句柄即可。但是因为 ext4 的延迟分配会导致写入被延迟和重新排序,rename("newfile", "file") 可以在 newfile 的内容实际写入磁盘内容之前执行,这出现了并行进行再次获得 file 坏版本的问题。

为了缓解这种情况,Linux 内核(自版本 2.6.30)尝试检测这些常见代码情况并强制立即分配。这会减少但不能防止数据丢失的可能性 -- 并且它对新文件没有任何帮助。如果你是一位开发人员,请注意:保证数据立即写入磁盘的唯一方法是正确调用 fsync()。

无限制的子目录
ext3 仅限于 32000 个子目录,ext4 允许无限数量的子目录。从 2.6.23 内核版本开始,ext4 使用 HTree 索引来减少大量子目录的性能损失。

日志校验
ext3 没有对日志进行校验,这给处于内核直接控制之外的磁盘或自带缓存的控制器设备带来了问题。如果控制器或具自带缓存的磁盘脱离了写入顺序,则可能会破坏 ext3 的日记事务顺序,从而可能破坏在崩溃期间(或之前一段时间)写入的文件。

理论上这个问题可以使用写入障碍(barrier)-- 在安装文件系统时,你在挂载选项设置 barrier=1,然后设备就会忠实地执行 fsync 一直向下到底层硬件。通过实践,可以发现存储设备和控制器经常不遵守写入障碍 -- 提高性能(和跟竞争对手比较的性能基准),但增加了本应该防止数据损坏的可能性。

对日志进行校验和允许文件系统崩溃后第一次挂载时意识到其某些条目是无效或无序的。因此这避免了回滚部分条目或无序日志条目的错误,并进一步损坏的文件系统 -- 即使部分存储设备假做或不遵守写入障碍。

快速文件系统检查
在 ext3 下,在 fsck 被调用时会检查整个文件系统 -- 包括已删除或空文件。相比之下,ext4 标记了 inode 表未分配的块和扇区,从而允许 fsck 完全跳过它们。这大大减少了在大多数文件系统上运行 fsck 的时间,它实现于内核 2.6.24。

改进的时间戳
ext3 提供粒度为一秒的时间戳。虽然足以满足大多数用途,但任务关键型应用程序经常需要更严格的时间控制。ext4 通过提供纳秒级的时间戳,使其可用于那些企业、科学以及任务关键型的应用程序。

ext3 文件系统也没有提供足够的位来存储 2038 年 1 月 18 日以后的日期。ext4 在这里增加了两个位,将 Unix 纪元扩展了 408 年。如果你在公元 2446 年读到这篇文章,你很有可能已经转移到一个更好的文件系统 -- 如果你还在测量自 1970 年 1 月 1 日 00:00(UTC)以来的时间,这会让我死后得以安眠。

在线碎片整理
ext2 和 ext3 都不直接支持在线碎片整理 -- 即在挂载时会对文件系统进行碎片整理。ext2 有一个包含的实用程序 e2defrag,它的名字暗示 -- 它需要在文件系统未挂载时脱机运行。(显然这对于根文件系统来说非常有问题)在 ext3 中的情况甚至更糟糕 -- 虽然 ext3 比 ext2 更不容易受到严重碎片的影响,但 ext3 文件系统运行 e2defrag 可能会导致灾难性损坏和数据丢失。

尽管 ext3 最初被认为“不受碎片影响”,但对同一文件(例如 BitTorrent)采用大规模并行写入过程的过程清楚地表明情况并非完全如此。一些用户空间的手段和解决方法,例如 Shake,以这样或那样方式解决了这个问题 -- 但它们比真正的、文件系统感知的、内核级碎片整理过程更慢并且在各方面都不太令人满意。

ext4 通过 e4defrag 解决了这个问题,且是一个在线、内核模式、文件系统感知、块和区段级别的碎片整理实用程序。在未来的 ext4 版本中仍然有一些关键功能要开发,包括元数据校验和、一流的配额支持和大分配块。

元数据校验和
由于 ext4 具有冗余超级块,因此为文件系统校验其中的元数据提供了一种方法,可以自行确定主超级块是否已损坏并需要使用备用块。可以在没有校验和的情况下,从损坏的超级块恢复 -- 但是用户首先需要意识到它已损坏,然后尝试使用备用方法手动挂载文件系统。由于在某些情况下,使用损坏的主超级块安装文件系统读写可能会造成进一步的损坏,即使是经验丰富的用户也无法避免,这也不是一个完美的解决方案!

与 Btrfs 或 ZFS 等下一代文件系统提供的极其强大的每块校验和相比,ext4 的元数据校验和的功能非常弱,但它总比没有好。虽然校验所有的事情 都听起来很简单!-- 事实上,将校验和与文件系统连接到一起有一些重大的挑战。

一流的配额支持
等等,配额?从 ext2 出现的那天开始我们就有了这些!是的,但它们一直都是事后的添加的东西,而且它们总是犯傻。这里可能不值得详细介绍,但设计文档列出了配额将从用户空间移动到内核中的方式,并且能够更加正确和高效地执行。

大分配块
随着时间的推移,那些讨厌的存储系统不断变得越来越大。由于一些固态硬盘已经使用 8K 硬件块大小,因此 ext4 对 4K 模块的当前限制越来越受到限制。较大的存储块可以显著减少碎片并提高性能,代价是增加“松弛”空间(当你只需要块的一部分来存储文件或文件的最后一块时留下的空间)。

ext4 的实际限制
ext4 是一个健壮、稳定的文件系统。如今大多数人都应该在用它作为根文件系统,但它无法处理所有需求。让我们简单地谈谈你不应该期待的一些事情 -- 现在或可能在未来:虽然 ext4 可以处理高达 1 EiB 大小(相当于 1,000,000 TiB)大小的数据,但你真的不应该尝试这样做。除了能够记住更多块的地址之外,还存在规模上的问题。并且现在 ext4 不会处理(并且可能永远不会)超过 50-100 TiB 的数据。ext4 也不足以保证数据的完整性。随着日志记录的重大进展又回到了 ext3 的那个时候,它并未涵盖数据损坏的许多常见原因。如果数据已经在磁盘上被破坏 -- 由于故障硬件或者只是数据随时间衰减 ext4 无法检测或修复这种损坏。

基于上面两点,ext4 只是一个纯文件系统,而不是存储卷管理器。这意味着,即使你有多个磁盘 -- 也就是奇偶校验或冗余,理论上你可以从 ext4 中恢复损坏的数据,但无法知道使用它是否对你有利。虽然理论上可以在不同的层中分离文件系统和存储卷管理系统而不会丢失自动损坏检测和修复功能,但这不是当前存储系统的设计方式,并且它将给新设计带来重大挑战。

与其它主流的文件系统相比较

XFS

XFS 与非 ext 文件系统在 Linux 中的主线中的地位一样。它是一个 64 位的日志文件系统,自 2001 年以来内置于 Linux 内核中,为大型文件系统和高度并发性提供了高性能(即大量的进程都会立即写入文件系统)。从 RHEL 7 开始,XFS 成为 Red Hat Enterprise Linux 的默认文件系统。对于家庭或小型企业用户来说,它仍然有一些缺点 -- 最值得注意的是,重新调整现有 XFS 文件系统是一件非常痛苦的事情,不如创建另一个并复制数据更有意义。虽然 XFS 是稳定的且是高性能的,但它和 ext4 之间没有足够具体的最终用途差异,以值得推荐在非默认(如 RHEL7)的任何地方使用它,除非它解决了对 ext4 的特定问题,例如大于 50 TiB 容量的文件系统。

XFS 在任何方面都不是 ZFS、Btrfs 甚至 WAFL(一个专有的 SAN 文件系统)的“下一代”文件系统。就像 ext4 一样,它应该被视为一种更好的方式的权宜之计。

ZFS

ZFS 由 Sun Microsystems 开发,以 zettabyte 命名 -- 相当于 1 万亿 GB -- 因为它理论上可以解决大型存储系统。作为真正的下一代文件系统,ZFS 提供卷管理(能够在单个文件系统中处理多个单独的存储设备),块级加密校验和(允许以极高的准确率检测数据损坏),自动损坏修复(其中冗余或奇偶校验存储可用),快速异步增量复制,内联压缩等,以及更多。

从 Linux 用户的角度来看,ZFS 的最大问题是许可证问题。ZFS 许可证是 CDDL 许可证,这是一种与 GPL 冲突的半许可的许可证。关于在 Linux 内核中使用 ZFS 的意义存在很多争议,其争议范围从“它是 GPL 违规”到“它是 CDDL 违规”到“它完全没问题,它还没有在法庭上进行过测试。”最值得注意的是,自 2016 年以来 Canonical 已将 ZFS 代码内联在其默认内核中,而且目前尚无法律挑战。

此时,即使我作为一个非常狂热于 ZFS 的用户,我也不建议将 ZFS 作为 Linux 的根文件系统。如果你想在 Linux 上利用 ZFS 的优势,用 ext4 设置一个小的根文件系统,然后将 ZFS 用在你剩余的存储上,把数据、应用程序以及你喜欢的东西放在它上面 -- 但把 root 分区保留在 ext4 上,直到你的发行版明确支持 ZFS 根目录。

Btrfs

Btrfs 是 B-Tree Filesystem 的简称,通常发音为 “butter” -- 由 Chris Mason 于 2007 年在 Oracle 任职期间发布。Btrfs 旨在跟 ZFS 有大部分相同的目标,提供多种设备管理、每块校验、异步复制、直列压缩等。截至 2018 年,Btrfs 相当稳定,可用作标准的单磁盘文件系统,但可能不应该依赖于卷管理器。与许多常见用例中的 ext4、XFS 或 ZFS 相比,它存在严重的性能问题,其下一代功能 -- 复制、多磁盘拓扑和快照管理 -- 可能非常多,其结果可能是从灾难性地性能降低到实际数据的丢失。

Btrfs 的维持状态是有争议的;SUSE Enterprise Linux 在 2015 年采用它作为默认文件系统,而 Red Hat 于 2017 年宣布它从 RHEL 7.4 开始不再支持 Btrfs。可能值得注意的是,该产品支持 Btrfs 部署用作单磁盘文件系统,而不是像 ZFS 中的多磁盘卷管理器,甚至 Synology 在它的存储设备使用 Btrfs,但是它在传统 Linux 内核 RAID(mdraid)之上分层来管理磁盘。



该文章最后由 阿炯 于 2023-07-11 12:46:42 更新,目前是第 2 版。