15.1 File system crash概述

(00:00 - 06:23,是在对Lock lab提问,与本节课无关故略过)

今天的课程是有关文件系统中的Crash safety。这里的Crash safety并不是一个通用的解决方案,而是只关注一个特定的问题的解决方案,也就是crash或者电力故障可能会导致在磁盘上的文件系统处于不一致或者不正确状态的问题。当我说不正确的状态时,是指例如一个data block属于两个文件,或者一个inode被分配给了两个不同的文件。

这个问题可能出现的场景可能是这样,当你在运行make指令时,make与文件系统会有频繁的交互,并读写文件,但是在make执行的过程中断电了,可能是你的笔记本电脑没电了,也可能就是停电了,之后电力恢复之后,你重启电脑并运行ls指令,你会期望你的文件系统仍然在一个好的可用的状态。

这里我们关心的crash或者故障包括了:在文件系统操作过程中的电力故障;在文件系统操作过程中的内核panic。包括XV6在内的大部分内核都会panic,panic可能是由内核bug引起,它会突然导致你的系统故障,但是你肯定期望能够在重启之后还能使用文件系统。

你可能会反问,怎么就不能使用文件系统了?文件系统不是存储在一个持久化的存储设备上吗?如果电力故障了,存储设备不会受影响,当电脑恢复运行时,存储设备上的block应该还保存着呀。我们将会看到很多文件系统的操作都包含了多个步骤,如果我们在多个步骤的错误位置crash或者电力故障了,存储在磁盘上的文件系统可能会是一种不一致的状态,之后可能会发生一些坏的事情。而这类问题就是我们今天主要关注的问题。这区别于另一类问题,比如说因为电力故障导致你的磁盘着火了,那么什么数据都没有了,这是一个完全不同的问题,并且有着不同的解决方法,这种情况下需要先备份你的文件系统,然后再重新安装文件系统等等。这个问题我们今天不会关心,今天我们关心的是包含了多个步骤的文件系统操作过程中发生的故障。

我们今天会研究对于这类特定问题的解决方法,也就是logging。这是一个最初来自于数据库世界的很流行的解决方案,现在很多文件系统都在使用logging。之所以它很流行,是因为它是一个很好用的方法。我们将会看到XV6中的logging实现。当然XV6的实现非常简单,几乎是最简单的实现logging的方法,因为我们只是为了演示关键的思想。但是即使是这么基本的logging实现,也包含了一些微妙的问题,我们将会讨论这些问题,这也是为什么文件系统的logging值得学习的原因。我们将会看到,由于XV6实现的较为简单,XV6中的logging存在一个缺点,它的性能并不咋样,尽管logging系统原则上来说可以获得好的性能。所以在下节课我们将通过学习Linux的ext3文件系统所使用的logging系统,来看一下如何实现一个高性能logging系统。

另外,这是我们最后一节有关XV6的课程。这节课之后,我们将切换到阅读论文。因为这节课讲完了之后,我们就覆盖了操作系统的基本概念,我们可以通过阅读论文看一些更高级的操作系统思想。

接下来让我们看一下这节课关注的场景。类似于创建文件,写文件这样的文件系统操作,都包含了多个步骤的写磁盘操作。我们上节课看过了如何创建一个文件,这里多个步骤的顺序是(注,实际步骤会更多,详见14.5):

  • 分配inode,或者在磁盘上将inode标记为已分配

  • 之后更新包含了新文件的目录的data block

如果在这两个步骤之间,操作系统crash了。这时可能会使得文件系统的属性被破坏。这里的属性是指,每一个磁盘block要么是空闲的,要么是只分配给了一个文件。即使故障出现在磁盘操作的过程中,我们期望这个属性仍然能够保持。如果这个属性被破坏了,那么重启系统之后程序可能会运行出错,比如:

  • 操作系统可能又立刻crash了,因为文件系统中的一些数据结构现在可能处于一种文件系统无法处理的状态。

  • 或者,更可能的是操作系统没有crash,但是数据丢失了或者读写了错误的数据。

我们将会看一些例子来更好的理解出错的场景,但是基本上来说这就是我们需要担心的一些风险。我不知道你们有没有人在日常使用计算机时经历过这些问题,比如说在电力故障之后,你重启电脑或者手机,然后电脑手机就不能用了,这里的一个原因就是文件系统并没有恢复过来。

Last updated