本节主要介绍分层转储的实现原理。
OceanBase 数据库的存储引擎采用 LSM-Tree 架构,数据大体上被分为 MEMTable 和 SSTable 两部分,当 MEMTable 的内存使用达到一定阈值时,就需要将 MEMTable 中的数据存储到磁盘上以释放内存空间,这个过程称为转储。在转储之前首先需要保证被转储的 MEMTable 不再进行新的数据写入,这个过程称为冻结(Minor Freeze),冻结会阻止当前活跃的 MEMTable 再有新的写入,同时会生成新的活跃 MEMTable。
分层转储
OceanBase 数据库支持分层转储策略。
分层转储内部实现原理如下图所示。

OceanBase 数据库的转储分为以下三层:
L0 层
L0 层内部称为 Mini SSTable。根据不同参数设置的不同转储策略,L0 层的 SSTable 可能存在也可能为空。
对于 L0 层,系统提供了 Server 级的配置项来设置 L0 层内部分层数和每层最大的 SSTable 的个数。L0 层内部分为
level-0到level-n层,每层最大容纳的 SSTable 个数相同。当 L0 层level-n的 SSTable 到达一定数目上限或阈值后开始整体合并,合并成一个 SSTable 写入level-n+1 层。当 L0 层的最大 Level 内的 SSTable 个数达到上限后,开始做 L0 层到 L1 层的整体合并来释放空间。在存在 L0 层的转储策略下,冻结 MEMTable 直接转储在 L0-level-0 写入一个新的 Mini SSTable,L0 层每个 Level 内的多个 SSTable 根据 base_version 有序,后续本层或跨层合并时需要保持一个原则,参与合并的所有 SSTable 的 Version 必须邻接,这样新合并后的 SSTable 之间仍然能维持 Version 有序,简化后续读取合并逻辑。L0 层的内部分层会延缓到 L1 的合并,更好地降低写放大,但同时会带来读放大,假设共 n 层,每层最多 m 个 SSTable,则最差情况 L0 层会需要持有
(n * m + 2)个 SSTable,因此实际应用中层数和每层 SSTable 上限都需要控制在合理范围。L1 层
L1 层内部称为 Minor SSTable,L1 层的 Minor SSTable 仍然维持 Rowkey 有序,每当 L0 层的 Mini SSTable 达到合并阈值后,L1 层的 Minor SSTable 开始参与和 L0 层的合并; 为了尽可能提升 L1 合并的效率,降低整体写放大,OceanBase 数据库内部提供了写放大系数设置,当 L0 层的 Mini SSTable 总大小和 L1 层的 Minor SSTable 的大小比率达到指定阈值后,才开始调度 L1 合并,否则仍在 L0 层内部合并。
L2 层
L2 层是基线 Major SSTable,为了保证多副本间基线数据完全一致,日常转储过程中 Major SSTable 仍保持只读,不发生实际的合并动作。
转储触发方式
转储支持自动触发和手动触发两种方式。




