MemTable 中的数据结构
OceanBase 数据库的内存存储引擎 MEMTable 由 BTree 和 Hashtable 组成,在插入/更新/删除数据时,数据被写入内存块,在 HashTable 和 BTree 中存储的均为指向对应数据的指针。

两种数据结构的特点
| 数据结构 | 优点 | 缺点 |
|---|---|---|
| HashTable | 插入一行数据的时候,需要先检查此行数据是否已经存在,当且仅当数据不存在时才能插入,检查冲突时,用 Hashtable 要比 BTree 快。 事务在插入或更新一行数据的时候,需要找到此行并对其进行上锁,防止其它事务修改此行,OceanBase 数据库的行锁放在行头数据结构中,需要先找到它,才能上锁。 | 不适合对范围查询使用 HashTable。 |
| BTree | 范围查找时,由于 BTree 中的数据都是有序的,因此只需要搜索局部的数据就可以了。 | 单行的查找,也需要进行大量的主键比较,从根结点找到叶子结点,而主键比较性能是较差的,因此理论上性能比 HashTable 慢很多。 |
在 OceanBase 数据库中, 对于用户表每个分区管理数据的基本单元就是 SSTable,当 MEMTable 的大小达到某个阈值后,OceanBase 数据库会将 MEMTable 冻结,然后将其中的数据转存于磁盘上,转储后的结构就称之为 SSTable 或者是 Minor SSTable。当集群发生全局合并时,每个用户表分区所有的 Minor SSTable 会根据合并快照点一起参与做 Major Compaction,最后会生成 Major SSTable。每个 SSTable 的构造方式类似,都是由自身的元数据信息和一系列的数据宏块组成,每个数据宏块内部则可以继续划分为多个微块,根据用户表模式定义的不同,微块可以选择使用平铺模式或者编码格式进行数据行的组织。

宏块
OceanBase 数据库将磁盘切分为大小为 2MB 的定长数据块,称之为宏块(Macro Block),宏块是数据文件写 IO 的基本单位,每个 SSTable 就由若干个宏块构成, 宏块2M固定大小的长度不可更改, 后续转储合并重用宏块以及复制迁移等任务都会以宏块为最基本粒度。
微块
在宏块内部数据被组织为多个大小为 16KB 左右的变长数据块,称之为微块(Micro Block),微块中包含若干数据行(Row),微块是数据文件读 IO 的最小单位。每个数据微块在构建时都会根据用户指定的压缩算法进行压缩,因此宏块上存储的实际是压缩后的数据微块,当数据微块从磁盘读取时,会在后台进行解压并将解压后的数据放入数据块缓存中。每个数据微块的大小在用户创建表时可以指定,默认 16KB,用户可以通过语句指定微块长度,但是不能超过宏块大小,语句如下。
ALTER TABLE mytest SET block_size = 131072;一般来说微块长度越大,数据的压缩比会越高,但相应的一次 IO 读的代价也会越大;微块长度越小,数据的压缩比会相应降低,但相应的一次随机 IO 读的代价会更小。另外根据用户表模式的不同,每个微块构建的时候可能以平铺模式(Flat)或编码模式(Encoding)分别进行构建。在目前版本中,只有基线数据可以指定使用编码模式组织微块,对于转储数据全部默认使用平铺模式进行数据组织。




