日志写

在执行 DML 操作时,为了保证事务性,会产生对应的 redo log,记录对数据行的插入/更新/删除操作,我们将这些日志称之为 clog。

OceanBase 数据库单台物理机上启动一个 observer 进程,有几万~十万 partition,所有 partition 同时共用一个 clog 文件,当写入的 clog 文件超过配置的阈值(默认为 64MB)时,会打开新的 clog 文件进行写入。

observer 收到的某个 partition leader 的写请求产生的 clog、其他节点 observer 同步过来的 clog(存在 partition 同在一个 paxos group),都写入 log buffer 中,由单个 IO thread 批量刷入 clog 文件。

写请求在 partition leader 所在 observer 上等待落盘同时并行同步给其他 observer, 多数派成功后返回 client 成功。

日志写.jpg

数据写

与传统数据库的刷脏页机制不同,OceanBase 数据库的存储引擎基于 LSM Tree 架构,对于数据块的写主要是在转储和合并阶段。在 MemTable 转储为 SSTable 时,也会在静态数据中记录当前的 clog 日志回放点,在转储完成之后,对应 clog 日志回放点之前的日志在理论上就可以被回收了,但通常这些日志文件并不会被立即删除,而是等到日志空间不足时再进行日志文件的重用。

在进行转储/合并时,对于一些较大的 SSTable,我们可能会将一个 SSTable 的数据拆分到多个线程中并行进行转储/合并,对于一张用户表,可以通过表级参数 tablet_size 来调整并行合并的粒度,当 SSTable 的大小超过表的 tablet_size 时,就会按照 tablet_size 对数据进行拆分,开启并行合并;但一般来说,并行合并的并行度不会超过配置的合并线程数。

查询流程

对于数据查询,大体上可以分为以下这么几种:单点查询 Get、多点查询 MultiGet、单 range 扫描、多 range 扫描,以及对于插入操作需要处理的 Exist 查询。

Get/MultiGet/Exist 的查询流程是类似的,如下图所示:

读写.jpg

Scan/MultiScan的查询流程是类似的,如下图所示:

读写2.jpg