openGauss源码解析(49)

openGauss源码解析:存储引擎源码解析(17)

4. cstore访存接口和索引机制

cstore访存接口如表4-30所示,主要包括扫描、插入、删除和查询操作。

表4-30 cstore访存接口

接口名称

接口含义

CStoreBeginScan

开启cstore扫描

CStore::RunScan

执行cstore扫描,根据执行计划,内层执行cstore顺序扫描或者cstore min-max过滤扫描

CStoreGetNextBatch

继续扫描,返回下一批向量数组

CStoreEndScan

结束cstore扫描

CStore::CStoreScan

cstore顺序扫描

CStore::CStoreMinMaxScan

cstore min-max过滤扫描

CStoreInsert::BatchInsert(VectorBatch)

将输入的向量数组批量插入cstore表中

CStoreInsert::BatchInsert(bulkload_rows)

将输入的多行数组插入cstore表中

CStoreInsert::BatchInsertCommon

将一批多行数组(最多MAX_BATCH_ROWS行)插入cstore表各个列的CU文件中、插入对应CUDESC表记录、插入索引

CStoreInsert::InsertDeltaTable

将一批多行数组插入cstore表对应的delta表中

InsertIdxTableIfNeed

将一批多行数组插入cstore表的索引表中

CStoreDelete::PutDeleteBatch

将一批待删除的向量数组暂存到局部数据结构中,如果达到局部内存上限,则触发一下删除操作

CStoreDelete::PutDeleteBatchForTable

CStoreDelete::PutDeleteBatch对于普通cstore表的内层实现

CStoreDelete::PutDeleteBatchForPartition

CStoreDelete::PutDeleteBatch对于分区cstore表的内层实现

CStoreDelete::PutDeleteBatchForUpdate

CStoreDelete::PutDeleteBatch对于更新cstore表操作的内层实现(更新操作由删除操作和插入操作组合而成)

CStoreDelete::ExecDelete

执行cstore表删除,内层调用普通cstore表删除或分区cstore表删除

CStoreDelete::ExecDeleteForTable

执行普通cstore表删除

CStoreDelete::ExecDeleteForPartition

执行分区cstore表删除

CStoreDelete::ExecDelete(rowid)

删除cstore表中特定一行的接口

CStoreUpdate::ExecUpdate

执行cstore表更新

cstore表查询执行流程,可以参考图4-26中所示。其中,灰色部分实际上是在初始化cstore扫描阶段执行的,根据每个字段的具体类型,绑定不同的CU扫描和解析函数,主要有FillVector、FillVectorByTids、FillVectorLateRead3类CU扫描解析接口。

图4-26 cstore表查询流程示意图

cstore表插入执行流程,可以参考图4-27所示。其中灰色部分内的具体流程可以参考图4-24、图4-25中所示。当满足以下3个条件时,可以支持delta表插入:

(1) 打开enable_delta_store GUC参数。
(2) 该批向量数组为本次导入的最后一批向量数组。
(3) 该批向量数组的行数小于delta表插入的阈值。

图4-27 cstore表插入流程示意图

cstore表的删除流程主要分为两步。

(1) 如果存在delta表,那么先从delta表中删除满足谓词条件的记录。
(2) 在CUDESC表中更新待删除行所在CU的删除位图记录。

cstore表的更新操作由删除操作和插入操作组合而成,流程不再赘述。

openGauss的cstore表支持psort和cbtree两种索引。

psort索引是一种局部排序聚簇索引。psort索引表的组织形式也是cstore表,该cstore表的字段包括索引键中的各个字段,再加上对应的行号(TID)字段。如图4-28所示,将一定数量的记录按索引键经过排序聚簇之后,与TID字段共同拼装成向量数组之后,插入psort索引cstore表中,插入流程和上面cstore表插入流程相同。

图4-28 psort索引插入原理图

查询时如果使用psort索引扫描,会首先扫描psort索引cstore表(扫描方式和上面cstore表扫描流程相同)。在一个psort索引CU的内部,由于做了局部聚簇索引,因此可以使用基于索引键的二分查找方式,快速找到符合索引条件的记录在该psort索引中的行号,该行的TID字段值即为该条记录在cstore主表中的行号。上述流程如图4-29所示。值得一提的是由于做了局部聚簇索引,因此在索引cstore表扫描过程中,在真正加载索引表CU文件之前,可以通过CUDESC中的min max做到非常高效的初筛过滤。

图4-29 psort索引查询原理图

cstore表的cbtree索引和行存储表的B-Tree索引在结构和使用方式上几乎完全一致,相关原理可以参考行存储索引章节(“4.2.5 行存储索引机制”节),此处不再赘述。

openGauss cstore表索引对外提供的主要接口如表4-31所示。

表4-31 cstore表索引对外接口

接口名称

接口含义

psortgettuple

通过psort索引,返回下一条满足索引条件的元组。伪接口,实际psort索引扫描通过CStore::RunScan实现

psortgetbitmap

通过psort索引,返回满足索引条件的元组的tid bitmap。伪接口,实际psort索引扫描通过CStore::RunScan实现

psortbuild

构建psort索引表数据。主要流程包括,从cstore主表中扫描数据、局部聚簇排序、插入到psort索引cstore表中

cbtreegettuple

通过cbtree索引,返回下一条满足索引条件的元组。内部和btgettuple都是通过调用_bt_gettuple_internal函数实现的

cbtreegetbitmap

通过cbtree索引,返回满足索引条件的元组的tid bitmap。内部和btgetbitmap都是通过调用_bt_next函数实现的

cbtreebuild

构建cbtree索引表数据。内部实现与btbuild类似,先后调用_bt_spoolinit、CStoreGetNextBatch、_bt_spool、_bt_leafbuild和_bt_spooldestroy等几个主要函数实现。与btbuild区别在于,B-Tree的构建过程中,扫描堆表是通过heapam接口实现的,而cbtree扫描的是cstore表,因此使用的是CStoreGetNextBatch

posted @ 2024-04-29 16:21  openGauss-bot  阅读(8)  评论(0编辑  收藏  举报