16.3 ext3 file system log format

ext3文件系统就是基于今天要阅读的论文,再加上几年的开发得到的,并且ext3也曾经广泛的应用过。ext3是针对之前一种的文件系统(ext2)logging方案的修改,所以ext3就是在几乎不改变之前的ext2文件系统的前提下,在其上增加一层logging系统。所以某种程度来说,logging是一个容易升级的模块。

ext3的数据结构与XV6是类似的。在内存中,存在block cache,这是一种write-back cache(注,区别于write-through cache,指的是cache稍后才会同步到真正的后端)。block cache中缓存了一些block,其中的一些是干净的数据,因为它们与磁盘上的数据是一致的;其他一些是脏数据,因为从磁盘读出来之后被修改过;有一些被固定在cache中,基于前面介绍的write-ahead rule和freeing rule,不被允许写回到磁盘中。

除此之外,ext3还维护了一些transaction信息。它可以维护多个在不同阶段的transaction的信息。每个transaction的信息包含有:

  • 一个序列号

  • 一系列该transaction修改的block编号。这些block编号指向的是在cache中的block,因为任何修改最初都是在cache中完成。

  • 以及一系列的handle,handle对应了系统调用,并且这些系统调用是transaction的一部分,会读写cache中的block

在磁盘上,与XV6一样:

  • 会有一个文件系统树,包含了inode,目录,文件等等

  • 会有bitmap block来表明每个data block是被分配的还是空闲的

  • 在磁盘的一个指定区域,会保存log

目前为止,这与XV6非常相似。主要的区别在于ext3可以同时跟踪多个在不同执行阶段的transaction。

接下来我们详细看一下ext3的log中有什么,这与XV6中的log有点不一样。在log的最开始,是super block。这是log的super block,而不是文件系统的super block。log的super block包含了log中第一个有效的transaction的起始位置和序列号。起始位置就是磁盘上log分区的block编号,序列号就是前面提到的每个transaction都有的序列号。log是磁盘上一段固定大小的连续的block。log中,除了super block以外的block存储了transaction。每个transaction在log中包含了:

  • 一个descriptor block,其中包含了log数据对应的实际block编号,这与XV6中的header block很像。

  • 之后是针对每一个block编号的更新数据。

  • 最后当一个transaction完成并commit了,会有一个commit block

因为log中可能有多个transaction,commit block之后可能会跟着下一个transaction的descriptor block,data block和commit block。所以log可能会很长并包含多个transaction。我们可以认为super block中的起始位置和序列号属于最早的,排名最靠前的,并且是有效的transaction。

这里有一些细节对于后面的内容很重要。在crash之后的恢复过程会扫描log,为了将descriptor block和commit block与data block区分开,descriptor block和commit block会以一个32bit的魔法数字作为起始。这个魔法数字不太可能出现在数据中,并且可以帮助恢复软件区分不同的block。

学生提问:有没有可能使用一个descriptor block管理两个transaction?是不是只能一个transaction结束了才能开始下一个transaction?

Robert教授:Log中会有多个transaction,但是的确一个时间只有一个正在进行的transaction。上面的图片没能很好的说明这一点,当前正在进行的transaction对应的是正在执行写操作的系统调用。所以当前正在进行的transaction只存在于内存中,对应的系统调用只会更新cache中的block,也就是内存中的文件系统block。当ext3决定结束当前正在进行的transaction,它会做两件事情:首先开始一个新的transaction,这将会是下一个transaction;其次将刚刚完成的transaction写入到磁盘中,这可能要花一点时间。所以完整的故事是,磁盘上的log分区有一系列旧的transaction,这些transaction已经commit了,除此之外,还有一个位于内存的正在进行的transaction。在磁盘上的transaction,只能以log记录的形式存在,并且还没有写到对应的文件系统block中。logging系统在后台会从最早的transaction开始,将transaction中的data block写入到对应的文件系统中。当整个transaction的data block都写完了,之后logging系统才能释放并重用log中的空间。所以log其实是个循环的数据结构,如果用到了log的最后,logging系统会从log的最开始位置重新使用。

记住这里的log的结构,它对于后面的内容也很重要。

Last updated