我正在尝试很好地掌握类 unix 文件系统中的影子分页;您可能会在ZFS或WAFL中看到的东西。似乎在影子分页中,当人们想要对页面进行更改时,会写入不同的页面或“影子页面”。操作完成后,即所有内容都已提交时,影子页面被写出,替换旧页面。这是对影子分页的正确(尽管是高级)理解吗?
影子分页与日志文件系统有何不同?它们看起来很相似。
感谢您的时间!
这两个系统都允许您通过不同的机制提供原子性/一致性:
当您修改某些内容时,影子分页总是分配一个新块,并且当一个块被覆盖时,它的旧副本变得空闲,因为任何其他活动文件系统块都不会引用它。崩溃一致性通过树上的递归元数据更新来实现——您更新叶块所在的位置(在修改期间复制到其他地方),并且必须更新其父块(在修改期间复制到其他地方)等等。文件系统的新版本当直到树根的整个链都被更新时,所有修改都变得可见。
日志允许您就地修改块,但您仍然需要将它们写入两次:一次写入标记您的意图的日志(并在需要时提供多更新原子性,例如实现将文件从一个目录移动到另一个目录),以及然后在日志本身中。由于您正在就地修改,因此对于同一块的覆盖,除了您覆盖的特定块之外,您通常不必更新许多其他文件系统树块,因为当您编写它们的新版本时这些块没有改变位置。
最大的区别是影子分页/写时复制使得在文件系统中实现快照变得超级容易——你需要做的就是跟踪文件系统树根的旧版本,以及它当时引用的任何东西. 在日志中,这要困难得多,因为任何块都可以在任何时候被覆盖,并且日志不是无限的——通常它会很快被覆盖,否则它会占用磁盘上的大量空间。
写时复制的最大缺点可能是,尤其是对于旋转磁盘,它往往会使您的数据变得非常碎片化,因此在对频繁更新的文件进行大量顺序读取时需要更多的磁盘寻道。ZFS 有这个问题,我认为后来的一些写时复制系统通过一些中间层将逻辑块地址映射到物理地址来解决这个问题,以允许对数据进行碎片整理。