写这篇博客的起因是在学习文件系统知识的时候对某个架构师讲的日志文件系统的知识产生了疑惑,他说日志文件系统里记录的是文件的变更记录,而不是文件真实的内容;当用户读取文件的时候,文件内容会在内存中还原。这个知识点勉强可以接受。他接着又说NTFS 和 Ext3 是日志文件系统,它们和 FAT 最大的区别在于写入到磁盘中的是日志,而不是数据。这时候我心里逐渐产生了疑问,如果Ext3是这样管理数据的,那么反复修改一个文件岂不是会占用越来越多的硬盘空间?好在现在已经进入AI时代,我向大模型咨询了这个问题,大模型说并不会。接着,我让大模型介绍一下日志文件系统,在介绍过程中,大模型说在传统文件系统(如 ext4)中,文件修改是就地更新。如果大模型说的对,ext4属于传统文件系统,那么作为前辈的ext3更应该是传统文件系统。到底是谁错了呢?

让我们一起来探寻真相吧。大模型在介绍的过程中提到了两个英文短语:Journaling File System和Log-Structured File System,翻译成中文分别是日志文件系统和日志结构文件系统。

日志文件系统(Journaling File System)

日志文件系统在存储数据之外,有一个专门的地方(循环日志)记录对文件系统的修改。它的目的是确保文件系统在系统崩溃时能保持一致性。[1]

我们以向硬盘写入x, y, z为例,来看一下日志文件系统是怎么工作的:[2][1]

  1. 写日志:TxBegin, x, y, z
  2. 等待上述数据写入硬盘
  3. 写日志:TxEnd
  4. 等待上述数据写入硬盘
  5. 将x, y, z写入硬盘实际位置(data blocks)
  6. 删除本条日志数据

一条日志数据

如果在这过程中系统崩溃了,恢复程序会检查日志是否有TxEnd,如果有则重做第5步,如果没有则忽略TxBegin和它后面的内容。

该方案也被称为物理日志,确保了数据的一致性,缺点是需要多次写硬盘。

此外,还有一些优化方案,比如:[2][1]

  1. 将x, y, z写入硬盘实际位置(data blocks)
  2. 等待上述数据写入硬盘
  3. 更新metadata信息(inode)
  4. 等待上述数据写入硬盘

该方案也被称为metadata日志或者逻辑日志,只能确保metadata的一致性,而不能确保数据的一致性(因为metadata在数据后面才写入)。

常见的日志文件系统有Ext3、Ext4、NTFS、APFS等。

日志结构文件系统(Log-Structured File System)

日志结构文件系统整个系统就是一个日志。

alt text

上图的Data中有3 4 5种数据类型,分别是数据块、inode、inode map、Checkpoint Region和segment summary block。除Checkpoint Region外所有数据都使用写时复制的方式被追加到日志的最后。Checkpoint Region(CR)的存储位置是固定的,它存储了所有的inode map地址。

alt text

  • 读取文件:

    1. 读取Checkpoint Region,找到inode map的地址
    2. 读取inode map,找到inode的地址
    3. 读取inode,找到数据块的地址
    4. 读取数据块
  • 写入文件:

    1. 写数据块
    2. 写inode
    3. 写inode map
    4. 更新Checkpoint Region中最新inode map的地址

由于日志结构文件系统不修改旧数据,因此对于已经不使用了的旧数据需要进行垃圾回收。这时候就需要介绍前面提到的第5种类型:segment summary block。它记录了从数据块到inode的映射,通过判断该数据块是否仍旧被引用来判断是否是垃圾。同样地,垃圾回收也采用写时复制的方式将整个segment中不是垃圾的数据复制到一个新的segment中。[2][3]

alt text

日志结构文件系统的特点是写入高效,但是随机读取非常慢。[1]

常见的日志结构文件系统有因为硬盘的读写速度都不快,虽然日志结构文件系统写入高效,但是当下的文件系统还是读多写少,因此日志结构文件系统不常见,多数处于实验性阶段。值得一提的是,在Flash存储中,YAFFS是一个优秀的例子。[1]

最后

通过以上的分析,我们知道了日志文件系统和日志结构文件系统的概念和特点。虽然它俩中文里都有一个“日志”,但其实指的是完全不一样的东西。

开篇某架构师说的2个观点都是错误的,日志文件系统和日志结构文件系统都会记录文件的真实内容,NTFS 和 Ext3写入磁盘的就是数据。一般在技术分享时出现一些小错误都可以理解,但是如此误人子弟的分享还是第一次见。

找到事情真相后,我开始好奇那位架构师在输出知识的时候有没有去求证过知识的正确性。假如那位架构师认为自己的知识十分正确,那么他在看到对这个知识的不同理解时是否会质疑自己?又假如那位架构师对自己掌握的知识存在疑问的话,他又是如何做到自信输出的?


  1. 1.https://www.quora.com/What-is-the-difference-between-a-journaling-vs-a-log-structured-file-system
  2. 2.https://www.cs.cornell.edu/courses/cs4410/2020fa/schedule/slides/LFS.pdf
  3. 3.https://people.kth.se/~johanmon/courses/id2206/lectures/journal-handout.pdf