在evict一章中我们简单描述了内存page在写盘时如何是选取磁盘写入位置的:
选择当前btree文件的空闲块中大小最合适的块,裁选出所需大小的块(如果没有这样的空闲块,那么向文件末尾写入)。
这一工作是通过block manager(__wt_block
)完成的,每个block manager代表了一个实际的table磁盘文件,其中包括了磁盘块分配、数据压缩等内容,整个模块解读起来稍显复杂。
但是幸运的是,对于磁盘块分配而言,我们并不需要过多关注block manager本身的具体结构与创建流程等,只需要掌握checkpoint与block manager的关系以及checkpoint的相关内容即可。
相信阅读完本章,WiredTiger写盘时的磁盘块选取问题将得到解答。
checkpoint结构
WiredTiger支持为每个表创建多个checkpoint。每个checkpoint都是只读的,作为所有对象的静态视图。一个checkpoint本质上是追踪了自上一个checkpoint以来完成的所有修改的log。
WiredTiger的checkpoint可以由任意字符串命名。未命名的checkpoint将使用“WiredTigerCheckpoint”的默认名称。
创建一个新的checkpoint会删除以前所有相同名称的checkpoints,以及所有名为“WiredTigerCheckpoint”的checkpoint,也就是说,任何名称的checkpoint都不会超过一个,创建一个新的checkpoint意味着无需维护以前的内存checkpoint。
如果当前要删除的checkpoint在cursor中处于打开状态,则创建新checkpoint的尝试将失败;如果checkpoints没有在cursor中打开则可以被删除。checkpoints是有序的,并维护了序号order。
尽管checkpoint是用于加快重启恢复,因此持久化后才能真正称作有效的checkpoint,但为了便于理解,我们将WiredTiger的checkpoint分为两类,一类是已经持久化的盘上的checkpoints,另一类是当前处在内存,可能发生更改的live checkpoint。
具体来说,一个已持久化的checkpoint包括以下几个部分:
root page
:root offset、root size以及root checksum,标识了该checkpoint所对应时段的b+tree的root page在磁盘上的位置
allocated lists
:每个entry表示在该checkpoint时间内,被分配用于写盘的extent
available lists
:每个entry表示在该checkpoint时间内,能够用于写盘的extent(空闲块)
discarded lists
:每个entry表示在该checkpoint时间内,与allocated lists中任何extent没有重叠部分的需要被回收的extent
file size
:table文件的大小
file write generation