在近代历史上,日志文件系统被认为十分奇特,主要是处于研究阶段。而如今,日志文件系统(ext3)已经成为 Linux 的缺省文件系统。本文向大家揭示了日志文件系统背后的一些思想,以及在电源故障或系统崩溃时,如何提供更好的完整性。此外本文还介绍了现行的几种日志文件系统和下一代日志文件系统。
定义日志文件系统的方法有很多种,但是让我们抓住要点。日志文件系统就是专为那些厌倦了一直盯着启动时 fsck(即文件系统一致性检查)的人而设计的(日志文件系统同样适用于希望文件系统具有故障恢复能力的群体)。如果系统采用传统的未提供日志功能的文件系统,那么操作系统在检测到系统为非正常关机时,会使用 fsck 应用程序执行一致性检验。该应用程序会扫描文件系统(这要花费很长的时间),并修复任何可安全修复的问题。而在某些情况下,当文件系统损坏严重时,操作系统会启动到单用户模式,由用户进行进一步的修复。
fsck 问题
更麻烦的是,为了确保文件系统元数据的正确性(即使未检测到损坏),操作系统会自动启动 fsck 进程。因此,避免对文件系统进行一致性检验正是需要改进的地方。
那么现在您应该清楚日志文件系统针对的是哪类人群了,但是他们是如何取缔 fsck 的呢?笼统地说,日志文件系统就是通过维护一份日志来防止文件系统崩溃。所谓日志就是一种特殊的文件,它会在一个循环的缓冲区内记录文件系统的修改,然后将其定期提交到文件系统。一旦系统发生崩溃,日志文件就会起到一个检查点的作用,用于恢复未保存的信息,防止损坏文件系统元数据。
总之,日志文件系统就是一种具有故障恢复能力的文件系统,它利用日志来记录尚未提交到文件系统的修改,以防止元数据破坏(请参见图 1)。但是如众多其他 Linux 解决方案一样,日志文件系统有多种方案供您选择。下面就让我们一起简短回顾一下日志文件系统的历史,然后再看一看现行的几种文件系统,看看它们之间有什么区别。
什么是元数据?
元数据 指磁盘上的数据的管理结构。它表示文件的创建与删除、目录的创建与删除、扩充文件、截取文件等。
图 1. 典型的日志文件系统
Linux 日志文件系统的历史
最早的日志文件系统是 IBM® Journaled File System(JFS)。JFS 于 1990 年首次发行,而当前 Linux 支持的版本是后期开发的 JFS2。1994 年,Silicon Graphics 为 IRIX 操作系统引进了高性能的 XFS。XFS 于 2001 年被植入 Linux 系统中。1998 年开发的智能文件系统(SFS)起初是为 Amiga 开发的,但之后却在 GNU Lesser General Public License(LGPL)下发行,并于 2005 年获得了 Linux 的支持。最常用的日志文件系统 ext3fs (third extended file system)是 ext2 的扩展,它增加了记录日志的功能。从 2001 年起,Linux 系统中就开始支持 ext3fs。最终,ReiserFS 日志文件系统在其被引入之后,力压群雄,被广泛使用。但由于其原开发者的一些法律纠纷,ReiserFS 日志文件系统未能得到进一步的发展。
日志的几种变体
日志文件系统是使用日志来缓冲文件系统的修改(同时也可以应用于紧急故障恢复)的,但可以根据记录的时间与内容采取不同的策略。其中,三种常见的策略为:回写(writeback)、预定(ordered)和数据(data)。
在回写模式 中,仅有元数据被记录到日志,数据块则被直接写入到磁盘位置上。这样可以保存文件系统结构,防止崩溃,但却有可能发生数据崩溃(比如:在元数据记录到日志后,数据块写入磁盘前,系统崩溃)。要想解决这个问题,您可以使用预定模式。预定模式 只将元数据记录到日志,但是在此之前将数据写入到磁盘。这样就可以保证系统恢复后数据和文件系统的一致性。最后一种模式将数据也记录到了日志中。在数据模式 中,元数据和数据都被记录到日志中。这种模式可以最大限度地防止文件系统崩溃与数据丢失,但由于全部数据都写入了两次(先写入日志,再写入磁盘),系统性能可能会降低。
日志的提交也有很多种不同的策略。比如,是在日志将满时,还是在超时后?
日志文件系统的现状
如今,有几种日志文件系统应用非常广泛。每一种都有其自己的优缺点。下面介绍现存最普遍的四种日志文件系统。
JFS2
JFS2(又称 enhanced journaled file system)是最早期的日志文件系统,在植入 Linux 之前已被应用于 IBM AIX® 操作系统多年。它是 64 位的文件系统,虽然它是在原来的 JFS 的基础上开发的,但却较之有所改进,即:JFS2 具有更优的扩展性能,而且支持多处理器架构。
JFS2 支持预定的日志记录方式,可以提高较高的性能,并实现亚秒级文件系统恢复。JFS2 同时为提高性能提供了基于分区的文件分配(Extent-based allocation)。基于分区的分配 是指对一组连续的块而非单一的块进行分配。由于这些块在磁盘上是连续的,其读取和写入的性能就会更好。这种分配的另外一个优势就是可以将元数据管理最小化。按块分配磁盘空间就意味着要逐块更新元数据。而使用分区,元数据则仅需按照分区(可以代表多个块)更新。
JFS2 还使用了 B+ 树,以便更快地查找目录和管理分区描述符。JFS2 没有内部日志提交策略,而是在 kupdate 守护进程超时时提交。
XFS
XFS 是 Silicon Graphicsis 于 1995 年为 IRIX 操作系统开发的其他早期日志文件系统之一。它于 2001 年就已经被植入 Linux,因此,它已经成熟而且可靠。
XFS 支持 64 位全地址寻址,并以 B+ 树为目录和文件分配提供高性能。XFS 同样使用了基于分区的分配,支持可变的块大小(从 512 字节到 64KB )。除分区外,XFS 还采用延时分配,即等到块将被写入磁盘时,再为其分配磁盘空间。这样所需磁盘空间总数就一目了然,因此这个功能提高了分配连续磁盘块的可能性。
XFS 还有一些其他的有趣特性,它可以保证 rate 输入输出(I/O — 通过为文件系统用户保留带宽)和直接 I/O。其中,数据是直接在磁盘和用户空间缓冲区间拷贝的(而不是从多个缓冲区进入)。XFS 采用回写日志策略。
第三扩展文件系统(ext3fs)
第三扩展文件系统(third extended file system,ext3fs)是最流行的日志文件系统,是由 ext2 文件系统演化而来。实际上,Ext3fs 可以与 ext2fs 兼容,这是因为 ext3fs 使用的结构与 ext2fs 相同,仅仅多了一个日志而已。我们甚至可以把 ext3fs 的一部分当作 ext2 文件系统挂载,或者将 ext2 文件系统转换成 ext3 文件系统(使用 tune2fs 实用程序)。
Ext3fs 允许用三种方式记录日志(回写,预定和数据),但预定模式为默认模式。日志提交策略也是可配置的,但是默认在日志填满 1/4 时或其中一个提交计时器超时时,提交日志。
ext3fs 主要的弊端之一就是它最初不是作为日志文件系统而设计的。它是在 ext2fs 的基础上开发的,因此缺少一些其他日志文件系统所具备的高级特性(例如分区)。它在性能方面较之 ReiserFS、JFS 以及 XFS 也尤为逊色,但它所需要的 CPU 和内存要比同类解决方案少。
ReiserFS
什么是 tail packing?
很多情况下,一些文件的大小小于逻辑块。为了不把可以分配给一个逻辑块的磁盘空间浪费给小文件(称之为tail),于是把多个文件打包到一个单一的逻辑块中。结果发现这种方法可以让磁盘空间的容量比其他竞争文件系统(有性能损失)高 5%。
ReiserFS 是从一开始就按照记录日志的意图而开发的日志文件系统。ReiserFS 于 2001 年被引进到主流 2.4 内核(Linux 采用的第一个日志文件系统)。其默认的日志记录方法为预定,且支持以在线调整大小的方式扩展文件系统。ReiserFS 同时还具有 tail packing 功能,显著减少了磁盘碎片。在处理较小文件方面,ReiserFS 的速度要比 ext3f 快(当 tail packing 可用时)。
ReiserFS(又称 ReiserFS v3)具有很多先进的功能,如 B+ 树。该文件系统的基础格式建立在单一的 B+ 树的基础之上,这使得搜索的效率和可伸缩性增强。提交策略则取决于日志的大小,但是要以待提交的块的数量为基础。
ReiserFS 也遇到了几个问题 — 大多是最近出现的,这与其开发者遇到了一些法律纠纷有直接原因。
日志文件系统的未来
现在您已经了解了现行的(和过去的)日志文件系统,下面就让我们看一看它的发展趋势。
Reiser4
在成功地将 ReiserFS 合并到 Linux 内核,并被很多的 Linux 发行版采用之后,Namesys(开发 ReiserFS 的公司)便开始致力于新的日志文件系统的开发。Reiser4 被设计成为全新的日志文件系统,它拥有很多先进的功能。
Resier4 拟定通过 wandering 日志和延迟分配块直至日志提交(像在 XFS 中一样)的方式来实现更优秀的日志记录。Reiser4 还设计有灵活的插件架构(以支持诸如压缩和加密之类的功能),但是被 Linux 社区拒绝了,因为这些在虚拟文件系统(virtual file system,VFS)被当作是最好的功能。
由于 Namesys 的所有者的坚持,所有关于 Reiser4 的商业活动都停止了。
第四扩展文件系统
第四扩展日志文件系统(fourth extended journaling file system,ext4fs)是由 ext3fs 演化而来。Ext4 文件系统被设计为具有向前和向后兼容性,但它具有许多新的高级特性(其中的一些特性破坏了兼容性)。这就意味着您可以将 ext4fs 的一部分作为 ext3fs 挂载,反之亦然。
首先,ext4fs 是 64 位文件系统,并被设计为可以支持很大的容量(1 exabyte)。它还可以使用分区,但是这样做将失去与 ext3fs 的兼容性。像 XFS 和 Reiser4 一样,ext4fs 还支持在必要时采取延时分配方式分配块(这样可以减少磁盘碎片)。日志的内容也已经执行过检查和(checksum),使日志更加可靠。ext4fs 并没有采用标准的 B+ 或者 B* 树,取而代之的是 B 树的一种变体,叫做 H 树,它支持更大的子目录(ext3 的上限为 32KB )。
虽然延时分配的方法可以减少磁盘碎片,但时间久了,一个大的文件系统可能会成为碎片。为解决这个问题,开发了在线磁盘碎片整理工具(e4defrag)。您可以使用这个工具来整理单个的文件或者整个文件系统。
ext3fs 与 ext4fs 间的另一个有趣的区别就在于文件的日期分辨率。在 ext3 中,时间戳的最小分辨率为 1 秒。而 Ext4fs 是面向未来的:那时处理器和接口的速度会持续加快,需要更高的分辨率。因此,ext4 中时间戳的最小分辨率为 1 纳秒。
Ext4fs 已被合并到自 2.6.19 以后的 Linux 内核中,但它还是不够稳定。下一代系统的开发将继续致力于此;辅之以上一代的优势, 它就会是下一代的 Linux 日志文件系统。
结束语
日志文件系统在系统崩溃或断电时提供了可靠性,并防止系统崩溃。另外,与较传统的文件系统方法(比如那些依赖于 fsck 的系统)相比,日志文件系统大大地缩短了系统崩溃的恢复时间。新的日志记录功能的开发要指望将来的新算法与结构,也要仰仗以前的算法与结构,将 JFS 和 XFS 的功能结合起来。将来日志文件系统到底会如何发展还不得而知,但可以确定的是它们会更具实用性,并会成为新的日志文件系统标准。