TokuDB checkpoint过程分为如下五个步骤:

  • 获取全局的checkpoint锁
  • Begin checkpoint
  • End checkpoint
  • 清理redo日志
  • 释放全局的checkpoint锁

下面我们一起看一下begin checkpoint和end checkpoint的详细过程。

  1. pin FT 给CACHEFILE对应的FT加pinned_by_checkpoint标记,保证CACHEFILE不会从内存里移除。CACHEFILE记录了索引包含的数据节点列表和描述索引对应文件的相关信息。

  2. 记redo日志 记录checkpoint开始时刻的lsn。 写redo日志:begin checkpoint日志项,checkpoint打开索引文件日志项,live txn日志项
  3. 对每个PAIR(数据页)加checkpoint_pending标记 遍历cachetable里面每个数据页,如果数据页对应的索引文件(CACHEFILE)属于checkpoint,对数据页加checkpoint_pending标记,并加入到全局m_pending_head双向链表里面。
  4. 更新checkpoint header信息 clone一份FT header,记做ft->checkpoint_header,记录checkpoint开始时刻BTT(Block Translation Table)的位置。 TokuDB每次checkpoint都会把数据写到一个新的地方,索引逻辑页号(或者块号)到索引文件offset的映射关系记录在BTT里面。 ft->checkpoint_header的类型为FT_CHECKPOINT_INPROGRESS,lsn为checkpoint开始时刻的lsn。
  5. 克隆BTT,BTT里面有个translation表,记录逻辑页号到索引文件offset的映射关系。这个表有三个版本:
  • _current(当前的,类型为TRANSLATION_CURRENT)
  • _inprogress(checkpoint开始时刻的,类型为TRANSLATION_INPROGRESS)
  • _checkpointed(上次checkpont的,类型为TRANSLATION_CHECKPOINTED)
    就是把TRANSLATION_CURRENT复制一份,并把类型设置为TRANSLATION_INPROGRESS。

在end checkpoint的阶段

  • 把所有的CACHEFIlE记录在checkpoint_cfs数组里面,为后面的步骤做准备。
  • 对checkpoint_cfs数组的每个CACHEFILE调用checkpoint_userdata回调函数(实际上是ft_checkpoint函数)把BTT(Block Translation Table)和ft->checkpoint_header序列化到磁盘上。 BTT的rootnum 在FT索引文件里有两个位置可以保存ft->header:偏移0和偏移4096。 TokuDB采用round robin的方式,把奇数次(1,3,5…)checkpoint的header存储在偏移为0的地方; 把偶数次(2,4,6,…)checkpoint的header存储在偏移为4096的位置上。 然后更新ft->h->checkpoint_lsn为checkpoint开始时刻的lsn。
  • 写redo日志:end checkpoint日志项。
  • 通知logger子系统logger->last_completed_checkpoint_lsn为checkpoint开始时刻的lsn。
  • 对checkpoint_cfs数组保存的每个CACHEFILE调用end_checkpoint_userdata回调函数(实际上是ft_end_checkpoint)把_checkpointed记录的上次checkpoint写回的数据页所占用空间释放掉。并且把这次checkpoint的BTT保存在_checkpointed,然后清空_inprogress,表示checkpoint结束,当前没有正在进行的checkpoint。在ft_end_checkpoint里面还做了一个事情就是把ft->checkpoint_header释放并置为空,到这里checkpoint的工作就完成了。
  • unpin FT

下面我们一起看一下checkpoint过程记录的redo日志:

  • Begin_checkpoint:表示begin checkpoint的日志项
  • Fassociate:表示打开的索引的日志项
  • End_checkpoint:表示end checkpoint的日志项