目录
openGauss数据库SQL引擎

openGauss数据库执行器技术

openGauss存储技术

一、openGauss存储概览

二、openGauss行存储引擎

三、openGauss列存储引擎

四、openGauss内存引擎

Ⅰ.内存引擎的兼容性设计

Ⅱ.内存引擎索引

Ⅲ.内存引擎的并发管制

Ⅳ.内存引擎的内存管控

Ⅴ.内存引擎的长久化

openGauss事务机制

openGauss数据库安全

openGauss存储技术

四.openGauss内存引擎

内存引擎作为在openGauss中与传统基于磁盘的行存储、列存储并存的一种高性能存储引擎,基于全内存态数据存储,为openGauss提供了高吞吐的实时数据处理剖析能力以及极低的事务处理时延,在不同业务负载场景下能够达到其余引擎事务处理能力的3~10倍不等。

内存引擎之所以有较强的事务处理能力,并不单是因为基于内存而非磁盘带来的性能晋升,而更多是因为其全面地利用了内存中能够实现的无锁化的数据及索引构造、高效的数据管控、基于NUMA架构的内存管控、优化的数据处理算法以及事务管理机制。

值得一提的是,尽管是全内存态存储,然而并不代表着内存引擎中的解决数据会因为系统故障而失落;相同的,内存引擎有着与openGauss原有机制相兼容的并行长久化、checkpoint(检查点)能力,使得内存引擎有着与其余存储引擎雷同的容灾能力以及主备正本带来的高牢靠能力。

内存引擎总的架构如图37所示。

图37 内存引擎总体架构图

能够看到,内存引擎通过原有的Foreign Data Wrapper(内部数据封装器)扩大能力与openGauss的优化执行流程相交互,通过事务机制的回调以及与openGauss相兼容的WAL机制,保障了与其余存储引擎在这一体系架构内的共存,保障了整体对外的统一体现;同时通过保护外部的内存治理构造、无锁化索引、乐观事务机制来为零碎提供极致的事务吞吐能力。

以下将逐渐开展解说相干关键技术点与设计。

内存引擎的兼容性设计01
因为数据状态的不同以及底层事务机制的差异,此处如何与一个以段页式为根底的零碎对接是内存引擎存在于openGauss中的重点问题之一。

此处openGauss原有的FDW(Foreign Data Wrapper)机制为内存引擎提供了一个很好的对接接口,优化器能够通过FDW来获取内存引擎外部的元信息,内存引擎的内存计算解决机制能够间接通过FDW的执行器接口算子实现间接调起、并通过雷同的构造将后果以合乎执行器预期的形式(比方Scan(扫描)操作的pipelining(流水线))将后果反馈回执行器进行进一步解决后(如排序、Group by(分组))返回给客户端利用。

与此同时内存引擎本身的Error Handling(错误处理机制),也能够通过与FDW的交互,提交给上次零碎,以此同步触发下层逻辑的相应错误处理(如回滚事务、线程退出等)。

内存引擎借助FDW的形式靠近无缝的工作在整个零碎架构下,与以磁盘为根底的行列存储引擎实现共存。

在内存引擎中Create Table(创立表)的实际操作流程如图38所示。

图38 内存引擎操作流程图

能够看到FDW充当了一个整体交互API的作用。实现中同时扩大了FDW的机制,使得其具备更齐备的交互性能,包含:

(1) 反对DDL接口;

(2) 残缺的事务生命周期对接;

(3) 反对checkpoint(检查点);

(4) 反对长久化WAL;

(5) 反对故障复原(Redo);

(6) 反对Vacuum(垃圾清理回收)。

借由FDW机制,内存引擎能够作为一个与原有openGauss代码框架异构的存储引擎存在于整个体系中。

内存引擎索引02
内存引擎的索引构造以及整体的数据组织都是基于Masstree实现的。主体如图39所示。


图39 内存引擎主体构造

在前序文章【如何把握openGauss数据库核心技术?秘诀三:拿捏存储技术(2)】中的图15,很好地出现了内存引擎的组织架构。

图15 MVCC判断流程

Primary Index(主键索引)在内存引擎的一个表中是必须存在的因素,因而要求表在组织时尽量存在primary index;如果不存在,内存引擎也会额定生成surrogate key(代理键)来用于生成Primary index。Primary Index指向各个代表各个行记录的Sentinel(行指针),由Sentinel来对行记录数据进行内存地址的记录以及援用。Secondary Index(二级索引)索引后指向一对键值,键值的value(值)局部为到对应数据Sentinel的指针。

Masstree作为Concurrent B+ tree(并行B+树),集成了大量B+树的优化策略,并在此基础上做了进一步的改进和优化。其大抵实现如图40所示。

图40 Masstree实现形式

Masstree实现比于传统的B-tree,Masstree实际上是一个相似于诸多B+-树以trie(前缀树)的组织模式重叠的Radix tree(基数树)模式,以Key(键)的前缀作为索引,每k个字节造成一层B+-树结构,在每层中解决Key(键)中这k个字节对应所需的insert/lookup/update/delete流程。图41为k=8时状况。

图41 k等于8时的Masstree

注:图来自于“Cache craftiness for fast multicore key-value storage” , Eddie Kohler et. al.

Masstree中的读操作应用了类OCC(Optimistic Concurrency Control,乐观并发管制)的实现,而所有的update(更新)锁仅为本地锁。在树的构造上,每层的interior node(外部节点)和leaf node(叶子节点)都会带有版本,因而能够借助version validation(版本查看)来防止fine-grained lock(细粒度锁)的应用。

Masstree除了lockless(无锁化)之外,最大的亮点是cache line(缓存块)的高效利用。Lockless自身肯定水平防止了lookup/insert/update操作相互invalidate共享cache line(生效共享缓存块)的状况。而基于prefix(前缀)的分层,辅以适合的每层中B+-树fanout(扇出)的设置,能够最大水平的利用CPU prefetch(预取)的后果(尤其是在树的深度遍历过程中),缩小了与DRAM交互带来的额定时延。

Prefetch(预取)在Masstree的设计中显得尤为要害,尤其是在Masstree从tree root(树根节点)向leaf node(叶子节点)遍历、也就是树的降落过程中。此过程中的执行时延大部分因为内存交互的时延组成,因而prefetch(预取)能够无效地进步masstree traverse(遍历)操作的执行效率以及cache line(缓存块)的应用效率(命中)。

未完待续......