数据整理的Compact流程 (二)|OceanBase数据转储合并技术解读(二)

上篇文章《数据整理的Compact流程 (一)|OceanBase数据转储合并技术解读(二)》中,有讲解到,在OceanBase数据库中,当MemTable写满时,将其下刷到Mini SSTable的过程包含两个步骤:第一步,是将原本可写的MemTable冻结转换为只读的Frozen MemTable;第二步,是将这个已冻结的只读Frozen MemTable持久化存储到磁盘上,形成Mini SSTable。今天,我们将详细探讨这一后续步骤,也就是"转储"的具体执行流程。

整个转储过程可以分为三个阶段:准备阶段、执行阶段以及收尾阶段。

准备阶段

准备阶段主要包括选择这次转储需要处理的Frozen MemTable、拆分此次转储任务的并行度等。

首先是选取Frozen MemTable。我们知道,写到MemTable上的每条数据都会先持久化到写前日志以防止宕机丢失,而由于写前日志追加写的性质,每条数据会拥有一个递增的日志序号,我们这里称其为log_scn。基于此,我们可以通过log_scn的范围来标识一个MemTable或者SSTable。

以下图为例,一共有4个Frozen MemTable,分别包含了log_scn在(0, 100],(100,500],(500,1500]和(1500,2000]的数据。其中(0,500]的两个Frozen MemTable已经合成了一个Mini SSTable,但因为某些原因暂时没有回收。由于(0,500]的两个Frozen MemTable已经持久化到SSTable,我们认为其对应的日志可以回收,因此会存在一个checkpoint_scn的日志序号,用来表示log_scn小于该值的数据都已经持久化到SStable了。

那么此时如果新的转储任务到了准备阶段,将通过checkpoint_scn把Frozen MemTable分为两部分,其中大于checkpoint_scn的Frozen MemTable被选取为此次转储所需要处理的MemTable。

当选取了Frozen MemTable后,我们会通过第一个Frozen MemTable来划分并行度以及并行区间。具体来说,首先以Frozen MemTable的数据量估计值与一个参数值的比值来得到并行度。我们希望每个子任务处理一个MemTable中约128MB的数据,因此这个参数值默认是128MB(对于想要自定义的用户来说,可以通过修改表属性TABLET_SIZE来更改)。然后我们根据并行度,将Frozen MemTable内的rowkey大致均分成几个区间。以下图为例,当并行度为4时,理想情况下Frozen MemTable会被分成4份,每份包含1/4 rowkey范围的数据。

执行阶段

执行阶段主要包括迭代行、整合行以及输出行等步骤。

这里我们以一个简化的示例来展开介绍。我们假设数据行是(rowkey, c1, c2, c3)的四列结构,当前转储需要处理以下两个Frozen MemTable,其中从上到下是按照从旧到新的顺序摆放。在MemTable中,每个rowkey都包含一个或多个节点,每个节点代表了对该rowkey对应数据行的一次操作(insert/delete/update)。

首先我们会为每个MemTable生成一个迭代器,每个迭代器将按照rowkey顺序依次迭代,每次将从n个迭代器中得到n行。在下面的例子中,两个迭代器会分别从两个Frozen MemTable中迭代出两行,其中iter1迭代时从最早的行insert开始,将rowkey_A的两行数据整合(fuse)成了一个新的完整行;而iter2则迭代出了一个部分行(只包含rowkey_A以及更新列c3的值)。

当得到n个迭代器吐出的n行后,我们会对结果进行rowkey的比较,从中得出rowkey最小的行。在上面的例子里,我们会得到具有相同rowkey_A的两行。接着我们会将比较后得到的多个具有相同rowkey的行进行整合(fuse),形成一个或多个数据行。下面的例子中,两个最小rowkey的行被整合成了一行,时间上更新的update c3操作被整合到了输出行中。

当我们得到一个最终的输出行后,首先会将其追加写入微块的缓冲区,当缓冲区达到微块大小后,将进行压缩,压缩后的微块数据将追加写入宏块缓冲区,直到宏块缓冲区写满后触发写盘的操作。这里为了简化,我们没有介绍宏块/微块的一些索引结构。

注:迭代行的过程我们省略了事务提交与否、多版本行的与事务相关的复杂概念,感兴趣的同学可以阅读一篇与此相关的博文来进一步了解。

收尾阶段

收尾阶段主要包括生成Mini SSTable、更新table_store以及回收MemTable。

以下图为例,两个Frozen MemTable经过迭代、整合、输出后得到了两个宏块,并且两个宏块在block file上处于并不连续的位置。我们将基于这两个宏块生成一个Mini SSTable结构,通过SSTable的元数据,我们能够定位到其包含宏块的物理位置(注:实现上OceanBase为微块构造了B树形式的索引结构,SSTable的元数据中只需要记录树根就可以方便地进行微块的定位)。接着由于table_store(这里我们可以理解为一个分区的LSM-Tree结构)的MemTable/SSTable组成发生了变化,我们会新生成一个table_store,其中包含新的Mini SSTable以及旧的Major SSTable。最后我们回收数据已被持久化到SSTable的Frozen MemTable。

这篇博客的内容大多基于ob_tablet_merge_task.cpp源码,欢迎大家前往阅读与学习,也欢迎在评论区讨论任何想法和问题。

相关推荐
冰 河2 天前
《Mycat核心技术》第21章:高可用负载均衡集群的实现(HAProxy + Keepalived + Mycat)
分布式·微服务·程序员·分布式数据库·mycat
韩曙亮5 天前
【系统架构设计师】数据库系统 ② ( 分布式数据库 | 分布式数据库 特点 | 分布式数据库 分层模式 | 两阶段提交协议 - 2PC 协议 )
数据库·分布式·系统架构·分布式数据库·软考·dbms·两阶段提交协议
ActionTech7 天前
ChatDBA VS DeepSeek:快速诊断 OceanBase 集群新租户数据同步异常
oceanbase·deepseek·chatdba·爱可生
码农老起7 天前
从Oracle到OceanBase数据库迁移:全方位技术解析
数据库·oracle·oceanbase
OceanBase数据库官方博客8 天前
数据文件误删除,OceanBase中如何重建受影响的节点
oceanbase·分布式数据库·运维管理·实践经验
码农老起11 天前
OceanBase数据库基于脚本的分布式存储层性能深度优化
数据库·分布式·oceanbase
码农老起11 天前
万亿级数据量的OceanBase应用从JVM到协议栈立体化改造实现性能调优
jvm·oceanbase
OceanBase数据库官方博客13 天前
OceanBase 读写分离最佳实践
oceanbase·分布式数据库·读写分离·最佳实践
OceanBase数据库官方博客15 天前
网易云信架构升级实践,故障恢复时间缩至8秒
oceanbase·分布式数据库·架构选型·布道师计划
OceanBase数据库官方博客17 天前
自然语言秒转SQL—— 免费体验 OB Cloud Text2SQL 数据查询
数据库·sql·ai·oceanbase·分布式数据库·向量·text2sql