rocksdb-doc-cn

在这个wiki中,我们解释文件在他们不再被需要的时候是如何被删除的。

SST文件

当压缩结束,输入的SST文件会被LSM树里输出的文件替代。然而,他们可能还不能马上被删除。依赖于旧版本的LSM树的进行中的操作 使得这些文件不能马上被删除,需要等待这些操作完成。参考我们如何追踪存活SST文件了解LSM树版本是怎么工作。

可以保留旧版本的LSM树的操作包括:

当没有操作固定一个旧的LSM树版本的SST文件时,这个文件才可以被删除。

这些可以删除的文件会通过两个机制被删除

引用计数

RocksDB在内存中为每个SST文件保留一份引用计数。每个LSM树的版本都会有对该版本的所有SST文件有一个引用计数。基于这个版本的操作(上面提到了)会持有LSM树的版本的引用计数,或者直接通过“super versoin”间接持有。一旦一个版本的引用计数归零,他会丢弃所有SST文件的引用计数。如果一个SST文件的引用计数归零,他就可以被删除了。通常他们会马上被删除,除了一下情况:

罗列所有文件,以找出过期文件

引用计数机制在大多数场景都是有用的。然而,引用计数不能持久化,所以一重启就丢失了,所以我们需要其他的机制来回收文件。重启DB的时候,我们做一次全量垃圾回收,然后根据options.background_purge_on_iterator_cleanup周期性执行清理。后面的选项只是为了保证安全。

在这个全量垃圾回收模式中,我们罗列DB目录里的所有文件,然后检查一个个文件比对检查所有的LSM树,看看是不是已经不用了。对于不需要的文件,我们删除他们。然而,并不是在DB目录,但是没有在存活版本的文件,就是没用的。对于正在进行中的压缩或者落盘创建的文件不应该被删除。为了阻止这个发生,我们使用一个好功能,他要求文件名单调递增。在落盘或者压缩开始前,我们记住当时最新的SST文件编号。如果一次全量垃圾回收在这个工作结束前开始了,所有编号大于该编号的SST文件会被保留。这个条件会在相关任务结束之后被释放。由于多个压缩和落盘工作可以并行运行,所有编号大于最早固定的SST文件编号的文件,都会被保留。可能我们会有一些假阳性,但是他们最终会被清理。

日志文件

一个日志文件在所有数据都落盘到SST文件之后就可以被删除了。对于一个单列族的DB,决定一个日志文件是否可以删除是非常简单的,对于多列族的DB,则稍微复杂点,更复杂的情况是,如果你开启了两阶段提交(2PC)的时候

单列族DB

一个日志文件与一个memtable有1:1对应关系。一旦一个memtable落盘了,对应的日志文件就会被删除。会在落盘工作的最后进行。

多列族DB

当有多个列族,一个新的日志文件会在任何一个列族落盘的时候创建。一个日志文件只可以在所有列族的数据都落盘的时候删除。RocksDB的实现方式是每个列族追踪 本列族 还有 未落盘数据的 最早的日志文件。一个日志文件只能在他比 所有列族各自的最早的日志 的最早那个还要早的时候,才能被删除。

两阶段提交

在两阶段提交中,有一次写入,有两个日志需要写:一个准备和一个提交。只有当提交了的日志落盘之后,我们才能释放包含准备日志和提交日志的文件。不再有一个简单的从memtable到日志文件的映射了。例如,考虑下面的一个DB列族的序列:

--------------
001.log
   Prepare Tx1 Write (K1, V1)
   Prepare Tx2 Write (K2, V2)
   Commit Tx1
   Prepare Tx3 Write (K3, V3)
-------------- <= Memtable Flush   <<<< Point A
002.log
   Commit Tx2
   Prepare Tx4 Write (K4, V4)
-------------- <= Memtable Flush   <<<< Point B
003.log
   Commit Tx3
   Prepare Tx5 Write (K5, V5)
-------------- <= Memtable Flush   <<<< Point C

在Ponit A,尽管memtable落盘了,001.log还是不能删除,因为Tx2和Tx3还没有提交。类似的,在PointB,001.log还是不能被删除,因为Tx3没有提交。只有到了PointC,001.log才可以删除。但是002.log还是不能删除,因为Tx4还没提交。

RocksDB会使用一个错综复杂的低锁数据结构来决定一个日志文件是不是可以被删除。

看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持! 觉得写的不错那就给点吧, 在线乞讨 微信转账