目录
openGauss数据库SQL引擎

openGauss数据库执行器技术

openGauss存储技术

一、openGauss存储概览

二、openGauss行存储引擎

三、openGauss列存储引擎

Ⅰ、列存储引擎的总体架构
Ⅱ、列存储的页面组织构造
Ⅲ、列存储的MVCC设计
IV、列存储的索引设计
V、列存储自适应压缩
VI、列存储的长久化设计
四、openGauss内存引擎

openGauss事务机制

openGauss数据库安全

openGauss存储技术

三.openGauss列存储引擎

列存的索引设计

04
列存反对的索引设计有:

§ Btree索引

§ 稠密索引

§ 聚簇索引

  1. 列存的Btree索引
    列存储引擎在Btree索引的反对角度,与传统的行存储引擎无实质差异。对于个别用于应答大数据批量剖析性负载的列存储引擎来说,Btree索引有助于帮忙列存储大大晋升本身的点查效率,更好的适应混合负载。

行存储相干Btree索引的索引页面上,存储的是[key -> ctid](键 -> ctid)的映射,在列存的场景下,这个映射仍旧为[key-> ctid],但列存储的构造并不能像行存一样,通过ctid中的block number(块号)和offset(偏移量)间接找到此行数据在数据文件页面中的地位。列存储ctid中记录的为(cu_id, offset),要通过CUDesc构造来进行查找。

在基于btree的扫描中,从索引中拿到ctid后,须要在对应的CUDesc表中,依据CUDesc在cu_id列的索引找到对应的CUDesc记录,并由此关上对应的CU文件,依据offset找到数据。

如果此操作设计大量的存储层性能开销,因而列存的btree索引,与列存的其余操作一样,对立都为批量操作。即会现依据btree索引找到ctid的汇合,而后对此汇合进行排序,再批量的对排序后的ctid进行CU文件级别的查找与操作。这样能够做到程序枯燥的索引遍历,大大减少了重复操作文件带来的CPU以及IO开销。

  1. 列存的稠密索引
    列存储引擎每个列自带min/max稠密索引,每个CUDesc存储该CU的最小值和最大值。

那么在查问的时候,能够依据查问条件做简略的min/max判断,如果查问条件不在(min,max)范畴内,必定不须要读取这个CU,能够大大地缩小IO读取,如图31所示。

图31 稠密索引图

注:txn_info 示意事务信息;CUPtr 压缩单元的指针;CUNone 示意必定不命中;CUSome 示意可能有数据匹配;CU_Full 示意压缩单元数据全命中。

  1. 列存的聚簇索引
    列存表在建设时能够抉择在列上建设聚簇索引(partial sort index)。

如果业务的初始数据模型较为离散,那么稠密索引不同CU之间的min、max就会有大量交加,这种状况下在给定谓词对列存表进行检索的过程中,会呈现大量的CU误读取,甚至可能导致其查问效率与全表扫描近似。如图32所示,查问2根本命中了所有CU,min-max索引没有可能无效筛选。

图32 数据模型较为离散时查问效果图

聚簇索引能够对局部区间内的数据做相应的排序(个别区间会蕴含多个CU所笼罩的行数),能够保障CU之前交加尽量少,能够极大地晋升在数据离散场景下稠密索引的效率。

其示意图如图33和图34所示。

图33 聚簇索引失效前

图34 聚簇索引失效后

同时,聚簇索引会使得CU外部的数据邻近有序,晋升CU文件自身的压缩比以及压缩效率。

列存储自适应压缩05
每个列自适应抉择压缩,反对delta value encoding(差分编码)、Run length encoding(游程编码)、dictionary encoding(字典编码)、LZ4、zlib等混合压缩。依据数据个性的不同,压缩比个别能够有3X~20X。

列存储引擎反对低、中、高三种压缩级别,用户在创立表的时候能够指定压缩级别。

导入1TB原始数据量,别离测试低、中、高三种压缩级别,入库后数据大小别离是100GB、73GB、61GB。如图35所示。

图35 压缩比示意图

每次数据导入,首先对每个列数据依照向量组装,对前几批数据做采样压缩,依据数值类型和字符串类型,会抉择尝试不同的压缩算法。一旦采样压缩实现后,接下来的数据就抉择优选的压缩算法了。如图36所示,次要分数值压缩和字符压缩。其中对Numeric小数类型,会转换为整数后,再依照数值压缩。对数值型字符串,也会尝试转换为整数再依照数值压缩。

图36 面向列的自适应压缩

列存储的长久化设计06
下面章节列存储的组织构造在MVCC机制中提到,列存的存储单位由CUDesc和CU文件独特组成,其中CUDesc记录了CU相干的元信息,管制其可见性,实际上充当了一个“代理”的角色。然而CUDesc和CU,本质上还是拆散的文件状态。CUDesc表,实质上还是行存储表,其长久化流程听从行存储的共享缓冲区脏页与Redo日志的长久化流程,在事务提交前,CUDesc的改变会被记录在Redo日志中进行长久化。单个CU文件自身,因为含有大量的数据,应用失常的事务日志进行长久化会须要耗费大量的事务日志,引入十分大的性能开销,并且复原也非常迟缓。因而依据其利用场景,append-only(仅容许追加)的属性,以及与CUDesc的对应关系,列存储的CU文件,为了确保CUDesc和CU长久化状态的统一,在事务提交、CUDesc对应事务日志长久化前,会后行强制刷盘(Fsync),来确保事务改变的长久化。

因为数据库主备机例的同步也依赖事务日志,而CU文件并不蕴含在事务日志内,因而在与列存储同步时,主备实例之间除去失常的日志通道外,还有连贯的数据通道,用于传输列存储文件。CUDesc的改变会通过日志进行同步,而CU文件则会被间接通过数据通道传输到备机实例,并通过bit change map(BCM)文件来记录主备机例之间文件的同步状态。

未完待续.......