暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

openGauss数据库源码解析系列文章——存储引擎源码解析(一)

Gauss松鼠会 2021-04-14
2167

Gauss松鼠会
学习 探索 分享数据库前沿知识 共建数据库技术交流圈
关注

OLTP、OLAP业务各自对数据库的存储引擎提出了不同的要求,而openGauss能够支持多个存储引擎来满足来自不同场景的业务诉求。本篇将从存储引擎整体架构及代码概览磁盘引擎两方面展开介绍,其中磁盘引擎从整体框架及代码概览、行存储统一访存接口两点展开讨论。

一、存储引擎整体架构及代码概览

从整个数据库服务的组成构架来看,存储引擎向上对接SQL引擎,为SQL引擎提供或接收标准化的数据格式(元组或向量数组);向下对接存储介质,按照特定的数据组织方式,以页面、列存储单元(CU,compression unit)或其他形式为单位,通过存储介质提供的特定接口,对存储介质中的数据完成读、写操作。在此基础之上,存储引擎通过日志系统提供数据的持久化和可靠性能力;通过并发控制(事务)系统保证同时执行的、多个读写操作之间的原子性、一致性和隔离性;通过索引系统提供对特定数据的加速寻址和查询能力;通过主备复制系统提供整个数据库服务的高可用能力。

|图1  openGauss存储引擎整体构架示意图|

图1是openGauss存储引擎整体构架的示意图。总体上,根据存储介质和并发控制机制,存储引擎分为磁盘引擎和内存引擎两大类。磁盘引擎主要面向通用的、大容量的业务场景,内存引擎主要面向容量可控的、追求极致性能的业务场景。在磁盘引擎中,为了满足不同业务场景对于数据不同的访问和使用模式,openGauss进一步提供了astore(append-store,追加写优化格式)、cstore(column store,列存储格式)以及可拓展的数据元组和数据页面组织格式。在内存引擎中,openGauss当前提供基于Masstree结构组织的mstore(memory-store,内存优化格式)数据组织格式。

上述几种引擎和存储格式的介绍如表1所示。

表1  openGauss存储引擎种类

父类

(存储介质和并发控制)

子类

(数据组织形式)

说明

磁盘引擎

(磁盘介质,

多版本和悲观并发控制(pessimistic concurrency controlPCC))

astore

追加写优化格式

主要面向通用的在线交易处理类业务应用场景,适合高并发、小数据量的单点或小范围数据读、写操作。astore为行存储格式,向上提供元组形式的读、写;向下以页面为单位通过可扩展的介质管理器对存储介质进行读、写操作;并通过页面粒度的共享缓冲区来优化读、写操作的效率。当前行存存储格式默认的介质管理器采用磁盘文件系统接口,后续可扩展支持块设备等其他类型的存储介质

cstore

列存储格式

面向联机分析处理类业务应用场景适合大数据量的复杂查询和数据导入cstore为列存存储格式,向上提供向量数组形式的读写接口向下以压缩单元为单位将数据保存在磁盘文件系统中(当前列存存储格式唯一支持的存储介质)。考虑到联机分析处理类业务通常以读操作为主因此还提供了以压缩单元为粒度的只读共享缓冲区,以加速压缩单元的读操作性能

扩展存储格式

对于行存储类存储格式openGauss提供了与上层SQL引擎对接的、统一的、可扩展的访存接口层table access method)。该行存储统一访存接口层为SQL引擎提供元组形式的读写接口,同时屏蔽了下层各种不同行存储类存储格式的内部实现,从而实现了SQL引擎与存储引擎(行存储类磁盘引擎)的解耦,大幅提升了不同存储格式之间的隔离性和开发效率

当前行存储类存储格式支持追加写优化的astore格式后续会支持更新写优化的ustore格式等其他数据组织格式

内存引擎

(内存介质,

乐观并发控制(OCCoptimistic concurrency control))

mstore

(内存存储格式)

mstore内存引擎面向超低时延和超高吞吐量的OLTP场景。数据以元组粒度存储于内存介质中,得益于内存介质读、写操作的超低时延(与磁盘介质相比),内存引擎可以提供极致的OLTP业务性能。内存引擎通过openGauss的外表访存接口实现与SQL引擎的数据交互

 openGauss存储引擎具有如下几个特点。
(1)统一的日志系统。
在openGauss的存储引擎中,磁盘引擎和内存引擎共用同一套日志系统,以保证在数据库故障恢复场景下,各个引擎内和各个引擎间的数据持久性和一致性。基于上述统一的日志系统,openGauss支持主、备机(主、备数据库服务进程)之间的流式日志复制,并通过Quorum复制协议,在保证复制一致性的前提下,尽可能降低日志同步对主机业务的影响。
(2)多种并发控制和事务系统。

在openGauss的存储引擎中,有两种并发控制和事务系统:适合高并发、高冲突、追求确定性结果的悲观并发控制机制;适合低冲突、短平快、低时延的乐观并发控制机制。

在磁盘引擎中,采用读写冲突优化的悲观并发控制机制:对于读、写并发操作,采用多版本并发控制(MVCC,multi-version concurrency control);对于写、写并发操作,采用基于两阶段锁协议(2PL,two-phase locking)的悲观并发控制(PCC,pessimistic concurrency control)。

在内存引擎中,采用乐观并发控制来尽可能降低并发控制系统对业务的阻塞,以获得极致的事务处理性能和时延。
(3)表级存储格式/存储引擎和跨格式事务。
在openGauss的存储引擎中,支持在建表语句中指定目标表的存储格式和存储引擎,即行存储astore、列存储cstore、内存mstore和后续扩展的其他存储格式或存储引擎。因此,在同一个数据库中,为了适配不同的业务场景,用户可以创建不同存储格式或不同存储引擎的表。进一步,当前openGauss在同一个事务内,支持对同一引擎不同存储格式的表的读写查询,这将极大地简化不同存储格式表中数据一致性、同步性和实时性的运维难度。后续openGauss版本计划支持跨引擎事务,这将使得openGauss数据库在面对多样化的业务场景时显得更为游刃有余。
(4)统一的行存储访存接口。

在openGauss的磁盘引擎中,行存储类存储格式是最传统也是使用场景最广泛的存储格式。针对不同的业务场景,行存储格式需要进行不同的优化和设计。为了便于后续新型行存储格式的扩展,在openGauss中提供了统一的行存储访存接口层,为上层SQL引擎屏蔽了底层不同的行存储数据组织形式。

对于不同的行存储数据格式,它们向上对接统一的行存储访存接口,向下共享缓冲区管理、事务并发控制、日志系统、持久化和故障恢复、主备系统、索引机制。同时,不同的行存储数据格式内部又实现了不同的元组和页面格式,以及在此之上的访存接口、元组多版本、页面多版本、空闲空间管理回收等不同功能。

openGauss存储引擎的代码主要位于“src/gausskernel/storage/”目录下,具体目录结构如下:

    --src
    --gausskernel
    --storage
    --access
    --buffer
    --bulkload
    --cmgr
    --cstore
    --dfs
    --file
    --freespace
    --ipc
    --large_object
    --lmgr
    --mot
    --page
    --remote
    --replication
    --smgr
    每个子目录都是一个相对独立的模块,和本章内容相关的如表2所示。

    表2  存储引擎子目录

    模块名
    子目录
    说明
    访存模块
    access子目录
    主要包括:各种行存储格式中,元组格式;元组与页面之间的转换和访存管理;元组扫描、插入、删除和更新功能的接口实现;几类索引,包括B-TreehashGINgeneralized inverted index,通用倒排索引)、GiSTgeneralized search tree通用搜索树)、psort(列存储局部排序索引),的访存管理和接口实现;各类数据库操作对应的日志实现和恢复机制;以及事务模块实现
    行存储共享缓冲区模块
    buffer子目录
    主要包括:行存储共享缓冲区的结构;物理页面和缓冲区页面的映射管理;缓存页面的加载和淘汰算法等
    列存储只读共享缓冲区模块
    cmgr子目录
    主要包括:cstore列存储格式只读共享缓冲区的结构;压缩单元和缓冲区的映射管理;缓冲压缩单元的加载和淘汰算法等
    列存储访存模块
    cstore子目录
    主要包含:cstore列存储格式中,向量数组与压缩单元之间的转换和访存管理;以及在此基础之上向量数组的扫描、插入、删除和更新功能的接口实现
    文件操作和虚拟文件描述符模块
    file子目录
    主要包含:磁盘文件系统存储介质的文件和目录操作;虚拟文件描述符的实现和管理
    行存储空闲空间管理模块
    freespace子目录
    主要包含:各种行存储格式中,页面空闲空间的管理
    内存引擎模块
    mot子目录
    主要包含:内存引擎的实现
    页面模块
    page子目录
    主要包含:各种行存储格式中,页面格式、页面校验、页面加密和页面压缩
    备机页面修复模块
    remote子目录
    主要包含:从备机获取完整页面或压缩单元,用于修复主机损坏的页面或压缩单元
    主备日志复制模块
    replication子目录
    主要包含:主备日志发送和接受线程的实现;流式日志同步功能的实现;Quorum复制协议的实现,逻辑日志的实现以及主备重建;主备心跳检测功能的实现
    存储介质管理模块
    smgr子目录
    主要包含:存储介质管理层的实现;磁盘文件系统(当前默认的存储介质)的基本功能接口实现
     除了以上的这些模块之外,storage目录下剩余的子目录分别属于:外表批量导入模块(bulkload子目录)、外表服务器连接模块(dfs子目录)、进程间通信模块(ipc子目录)、大对象模块(large_object子目录)、锁管理模块(lmgr子目录)。
    openGauss存储引擎相关的后台线程实现代码包含在“src/gausskernel/process/postmaster”目录下,简要介绍如表3。在后序介绍具体相关模块消息序列时会详细介绍这些线程的工作原理和执行流程。
    表3  存储引擎后台线程

    线程名

    文件名

    说明

    ADIO线程

    aiocompleter.cpp

    该线程主要负责异步-同步读写操作ADIOasynchronous-direct input-ouput)的后台预取和回写

    autovacuum线程

    autovacuum.cpp

    该线程主要负责磁盘引擎的后台空闲空间回收

    bgwriter线程

    bgwriter.cpp

    该线程主要负责行存储表的后台脏页写入磁盘(当内存数据页跟磁盘数据页内容不一致的时候,称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”)

    cbmwriter线程

    cbmwriter.cpp

    该线程主要负责增量页面修改信息的后台异步提取和CBMchanged block map,修改页面位图)日志的记录

    checkpointer线程

    checkpointer.cpp

    该线程主要负责在后台定期推进数据库的故障恢复点

    lwlockmonitor线程

    lwlockmonitor.cpp

    该线程主要负责业务线程轻量级锁的死锁检测

    pagewriter线程

    pagewriter.cpp

    该线程主要负责行存储共享缓冲区的脏页写入磁盘

    pgarch线程

    pgarch.cpp

    该线程主要负责在后台定期执行日志归档命令

    remoteservice线程

    remoteservice.cpp

    该线程主要负责接受主机页面修复RPCremote procedure call,远程函数调用)请求

    startup线程

    startup.cpp

    该线程为数据库故障恢复和回放日志的主线程

    walwriter线程

    walwriter.cpp

    该线程主要负责在后台异步写入磁盘日志

    二、磁盘引擎

    磁盘引擎是数据库系统中最常用的存储引擎,openGauss提供不同存储格式的磁盘引擎来支持大容量(数据量大于内存空间)场景下的OLTP、OLAP和HTAP(hybrid transactions and analytics processing,混合交易和分析处理)业务。本节主要介绍openGauss数据库内核中磁盘引擎的实现方式。

    (一)磁盘引擎整体框架及代码概览

    磁盘引擎的整体框架如图1中所示。根据与上层SQL引擎之间交互的数据结构类型,可以分为行存储格式和列存储格式。这两种数据格式共用相同的事务并发控制、日志系统、持久化和故障恢复、主备系统。

    在此基础之上,行存储格式内部设计为可以支持多种不同子格式的可扩展架构。不同行存储子格式之间共用相同的行存储统一访存接口(table access method)、共享缓冲区、索引机制等。当前仅支持追加写优化的astore子格式,后续计划支持写优化的ustore子格式以及面向其他场景优化的其他子格式。另一方面,在openGauss行存储格式中,对同一行数据的写-写查询冲突通过两阶段锁协议来实现并发控制(参见第5章中关于行级锁的介绍),对同一行数据的读-写查询冲突通过行级多版本技术来实现互不阻塞的、高效的并发控制。对于不同的行存储子格式,可能采用不同的行级多版本实现方式,从而也会引入不同的、清理历史版本的空闲空间管理和回收机制。

    磁盘引擎的主要功能模块和代码分布如表4所示。
    表4  磁盘引擎功能模块

    功能模块名

    说明

    行存储统一访存管理

    向上对接SQL引擎,提供对行存储表各类访存操作的抽象接口,包括:行级查询、插入、删除、修改等操作接口;向下根据行存储表实际的行存储子格式,调用与子格式对应的具体访存操作实现

    代码主要在src/gausskernel/storage/access/table目录下

    astore访存管理

    提供astore行存储格式表的具体访存操作实现包括:对astore堆表的行级查询、插入、删除、修改等操作接口;astore堆表行级多版本机制和元组可见性判断;根据astore堆表页间、页内结构,以及astore堆表元组结构,完成对astore堆表文件的遍历和增删改查操作

    代码主要在“src/gausskernel/storage/access/heap”目录(单表文件管理)和“src/gausskernel/storage/access/hbstore”目录(段页式文件管理)下

    astore堆表/索引表页面结构

    包括astore堆表/索引表元组在页面内的具体组织形式,在页面内插入元组操作、页面整理操作、页面初始化、页面加解密、页面CRCcyclic redundancy check,循环冗余码校验)校验操作等

    代码主要在“src/gausskernel/storage/access/redo/bufpage.cpp”文件、“redo_bufpage.cpp”文件和对应头文件

    astore堆表元组结构

    包括astore堆表元组的结构、填充、解构、修改、字段查询、变形、压缩、解压等操作

    代码主要在“src/gausskernel/storage/access/common/heaptuple.cpp”文件和对应头文件

    行存储索引访存管理

    向上对接SQL引擎,提供对索引表的行级查询、插入、删除等操作接口;向下根据索引表页间、页内结构,以及索引表元组结构,完成对指定索引键的查找和增删操作

    索引访存层抽象框架代码在“src/gausskernel/storage/access/index”目录下,每种索引结构具体对应的实现代码在同级的gin目录、gist目录、hash目录、nbtree目录、spgist目录

    行存储索引表元组结构

    包括行存储索引表元组的结构、填充、解构、拷贝等操作

    代码主要在“src/gausskernel/storage/access/common/indextuple.cpp”文件和对应头文件

    行存储共享缓冲区管理

    包括共享缓冲区的结构、页面查找方式、页面淘汰方式等

    代码主要在“src/gausskernel/storage/buffer”目录下

    行存储介质管理器管理和堆表/索引表文件管理

    包括几种主要介质操作的抽象接口以及几种主要的、基于磁盘文件系统的堆表/索引表文件操作接口

    代码在“src/gausskernel/storage/smgr”目录下

    cstore访存管理

    向上对接SQL引擎提供对cstore列存储表的向量数组(vector batch)粒度的查询插入删除修改等操作接口;向下根据cstore列存储表CUCU内结构,完成对cstore列存储表文件的遍历和增删改查操作;cstore列存储表CU内和CU间的多版本并发控制和可见性判断

    代码主要在“src/gausskernel/storage/cstore目录下cstore_系列文件中

    cstore索引访存管理

    向上对接SQL引擎,提供对cstore索引表的向量数组粒度的查询插入等操作接口;向下根据cstore索引表组织结构,完成对指定索引键的查询和插入等操作

    代码主要在“src/gausskernel/storage/access/cbtree目录cstore列储存B-Tree索引下和src/gausskernel/storage/access/psort目录cstore列存储psort索引

    cstore列存储表

    CU结构

    和行存不同,cstore列存储表与外存的I/O单元为CU。该部分主要包括CU的内部结构CU的填充和压缩等操作 

    代码在“src/gausskernel/storage/cstore/cu.cpp”文件

    cstore列存储表

    CU只读共享缓冲区管理

    包括以CU单位的只读共享缓冲区的结构、查找、淘汰等

    代码主要在“src/gausskernel/storage/cmgr目录下

    cstore列存储表

    CU持久化介质模块

    包括以CU为粒度的、基于磁盘介质的cstore列存储表文件外存I/O操作

    代码在“src/gausskernel/storage/cstore/custorage.cpp文件中

    预写日志共享缓冲区和文件管理

    包括日志记录格式、日志页面格式、日志文件格式、日志插入、日志写入磁盘、日志缓冲区管理、日志归档、日志恢复等操作

    代码在“src/gausskernel/storage/access/transam/xlog”系列文件中

    检查点和故障恢复管理

    包括页面淘汰算法和检查点推进算法、双写刷盘(写入磁盘)、页面故障恢复等

    代码主要分布在“src/gausskernel/process/postmaster/pagewriter.cpp”、“src/gausskernel/process/postmaster/bgwriter.cpp”、“src/gausskernel/storage/access/transam/double_write.cpp”、“src/gausskernel/storage/access/transam/xlog.cpp”、对应头文件和“src/gausskernel/storage/access/redo”目录

    事务管理和并发控制

    包括锁管理、事务提交流程、快照维护、提交时间戳维护、可见性判断等

    代码主要在“src/gausskernel/storage/access/transam”目录下

    该部分内容较为复杂,在第5章单独介绍

    事务提交日志SLRUSimple Least Recently Used,简单最近最少使用)共享缓冲区和文件管理

    包括事务提交日志的页面格式、读写操作、SLRU缓存算法、清理操作等,与事务管理模块一起介绍

    事务提交时间戳日志SLRU共享缓冲区和文件管理

    包括事务提交日志(csnlog)的页面格式、读写操作、SLRU缓存算法、清理操作等,与事务管理模块一起介绍

    关键控制文件管理

    主要包括控制文件、根系统表文件等关键文件的读、写操作

    代码分布较广

    在上述模块基础之上,openGauss磁盘引擎还包括CU压缩、外表、批量导入等功能,代码分布在“src/gausskernel/storage/cstore/compression”、“src/gausskernel/storage/access/dfs”、“src/gausskernel/storage/bulkload”等目录下。

    openGauss磁盘引擎的关键技术整体来说包括:

    (1)基于事务提交逻辑时间戳的快照隔离机制以及多版本并发控制技术。
    (2)基于事务号(xid,全称transaction identifier)的行级多版本管理技术。
    (3)基于大内存设计的共享缓冲区管理和淘汰算法。
    (4)平滑无性能波动的增量检查点(checkpoint)技术。
    (5)基于并行回放的快速故障实例恢复技术。
    (6)支持事务语义的DML操作和DDL操作。
    (7)面向OLAP场景的cstore列存储格式。当表中列数比较多、但是访问的列数比较少时可以大大减少不必要的列的I/O开销。
    (8)面向OLAP场景的cstore列存储批量访存接口。向上支持以向量数组为粒度的批量数据访存接口,结合向量化执行引擎提升CPU缓存命中率和系统吞吐率。
    (9)面向OLAP场景的cstore列存储高效压缩算法。基于同一列比较相似的数据特征,在大数据量下获得很高的压缩效果,减少系统的I/O开销。

    (二)行存储统一访存接口

    如上所述,在openGauss中,提供行存储统一访存接口层,来屏蔽不同行存储子格式内部实现机制对SQL引擎的影响。该行存储统一访存接口层被称为Table Access Method层。根据SQL引擎对行存储表的访存方式,将访存接口分为5类,如表5所示。每一类接口的具体操作如表6至表10所示。

    表5  Table Access Method定义的访存接口

    接口类别

    接口含义

    Tuple AM

    Slot AM

    元组(tuple)和元组槽(slot)操作抽象层,包括元组数据结构的抽象、元组操作的抽象,执行引擎无须关注元组属于哪种行存储子格式,只需调用元组数据结构基类的抽象操作接口,就可操作不同行存储子格式的元组,从而屏蔽不同行存储子格式物理元组结构、访问方法的差异

    TableScan AM

    表扫描(table scan)抽象层,包括TableScan数据结构的抽象、TableScan管理操作的抽象,执行引擎无须关注行存储子格式内部TableScan结构的差异,通过调用TableScan数据结构基类的抽象管理接口,就可完成不同行存储子格式的TableScan管理,屏蔽不同行存储子格式内部实现的差异

    DQL AM

    元组查询(data query languageDQL)操作抽象层,包括获取元组、元组可见性判断等查询操作的抽象

    DML AM

    元组写操作抽象层,包括元组插入、批插、删除、更新、锁定等接口的抽象

    DDL AM

    表物理操作抽象层,这里统称为DDL抽象层,涉及表物理文件操作的相关接口的抽象,例如CTASTRUNCATELOAD/COPYVACUUMVACUUM FULLANALYZEREBUILD INDEXALTER TABLE RESTRUCTDDL语法。该层也可以支持存储管理的抽象功能,如屏蔽不同行存储子格式的文件/目录管理模块、SMGR访问等差异

    表6  Tuple AM、Slot AM类访存接口

    接口名称

    接口含义

    tableam_tslot_clear

    清理slot tuple主要是被ExecClearTuple调用

    tableam_tslot_materialize

    该方法在ExecMaterializeSlot被调用slot中的tuple进行local copy(本地拷贝)

    tableam_tslot_get_minimal_tuple

    获取slot中的minimal tuple(最小化元组),slot负责管理/释放minimal tuple的内存

    tableam_tslot_copy_minimal_tuple

    返回slotminimal tuple的副本,该副本在当前内存上下文中被分配,需要调用者进行释放操作

    tableam_tslot_store_minimal_tuple

    此函数在指定的TupleTableSlot结构体中存储minimal tuple

    tableam_tslot_get_heap_tuple

    该函数获取slot中的tuple

    tableam_tslot_copy_heap_tuple

    该函数返回slottuple的副本,该副本在当前内存上下文中被分配,需要调用者进行释放操作

    tableam_tslot_store_tuple

    该方法将对应的物理元组存储到slot

    tableam_tslot_getsomeattrs

    强制更新slottuple某个属性的valuesisnull数组信息

    tableam_tslot_getattr

    获取当前slottuple的某个属性信息

    tableam_tslot_getallattrs

    强制更新slottuplevaluesisnull数组

    tableam_tslot_attisnull

    检查slottuple的属性是否为null

    tableam_tslot_get_tuple_from_slot

    slot中获取一个tuple,并根据relation结构体中行存储子格式信息转换为对应子格式的tuple

    tableam_tops_getsysattr

    获取tuple的系统属性

    tableam_tops_form_minimal_tuple

    根据valuesisnull数组内容,新建一个tuple

    tableam_tops_form_tuple

    根据valuesisnull数组内容,新建一个minimal tuple

    tableam_tops_form_cmprs_tuple

    根据valuesisnull数组内容,新建一个被压缩的tuple

    tableam_tops_deform_tuple

    抽取指定tuple中的data数据到valuesisnull数组

    tableam_tops_deform_cmprs_tuple

    抽取被压缩的tuple中的data数据到valuesisnull数组

    tableam_tops_computedatasize_tuple

    计算需要构造的tupledata区域的大小

    tableam_tops_fill_tuple

    根据valuesisnull数组中的数据填充到tupledata区域

    tableam_tops_modify_tuple

    根据一个旧tuple新建一个tuple并更新其values

    tableam_tops_free_tuple

    释放一个tuple的内存

    tableam_tops_tuple_getattr

    获取tuple的某个属性信息

    tableam_tops_tuple_attisnull

    检查tuple的属性是否为null

    tableam_tops_copy_tuple

    拷贝并返回一个tuple

    tableam_tops_copy_minimal_tuple

    拷贝并返回一个minimal tuple

    tableam_tops_free_minimal_tuple

    释放minimal tuple的内存

    tableam_tops_new_tuple

    新建一个tuple

    tableam_tops_destroy_tuple

    销毁一个tuple

    tableam_tops_get_t_self

    获取tuple中的self指针,指向自己在表中的位置

    tableam_tops_exec_delete_index_tuples

    删除索引的tuple

    tableam_tops_exec_update_index_tuples

    更新索引的tuple

    tableam_tops_get_tuple_type

    获取tuple属于哪种存储引擎

    tableam_tops_copy_from_insert_batch

    copy from场景进行批量INSERT(插入)

    tableam_tops_update_tuple_with_oid

    根据table OID(表的唯一标识号)更新tuple

    表7  TableScan AM类访存接口

    接口名称

    接口含义

    tableam_scan_begin

    初始化scan结构体,准备执行table scan(全表扫描)算子

    tableam_scan_begin_bm

    准备执行bitmap scan(位图扫描)算子

    tableam_scan_begin_sampling

    初始化堆表(顺序)扫描操作

    tableam_scan_getnexttuple

    返回scan中的下一个tuple

    tableam_scan_getpage

    获取scan中的下一页

    tableam_scan_end

    结束scan,并释放内存

    tableam_scan_rescan

    重置scan

    tableam_scan_restrpos

    重置扫描位置

    tableam_scan_markpos

    记录当前扫描位置

    tableam_scan_init_parallel_seqscan

    初始化并行sequence scan(顺序扫描)

    表8  DQL AM类访存接口

    接口名称

    接口含义

    tableam_tuple_fetch

    根据tid(元组物理位置)获取tuple

    tableam_tuple_satisfies_snapshot

    指定元组对于快照是否可见

    tableam_tuple_get_latest_tid

    获取tid指向的当前snapshot(快照)可见的最新物理元组

    表9  DML AM类访存接口

    接口名称

    接口含义

    tableam_tuple_insert

    插入一条元组到表中

    tableam_tuple_multi_insert

    插入多条元组到表中

    tableam_tuple_delete

    删除一条元组,返回并发冲突状态,由调用者根据并发冲突状态决定下步操作

    tableam_tuple_update

    更新一条记录,返回并发冲突状态,由调用者根据并发冲突状态决定下步操作

    tableam_tuple_lock

    锁定一条元组

    tableam_tuple_lock_updated

    解锁一条元组

    tableam_tuple_check_visible

    检查元组的可见性

    tableam_tuple_abort_speculative

    终止upsert操作的尝试插入操作,转为更新操作

    表10  DDL AM类访存接口

    接口名称

    接口含义

    tableam_index_build_scan

    该方法用于创建索引的首次全表扫描

    tableam_index_validate_scan

    该方法用于并发创建索引的第二次全表扫描

    tableam_relation_copy_for_cluster

    将源表数据根据指定的聚簇方式复制到新表中

    对于每一个行存储子格式,需要提供上述这五类访存接口的各自实现方式,并注册到g_tableam_routines全局行存储访存接口数组中。SQL引擎在调用某个访存接口时,根据Relation结构体中表的子格式类型(rd_tam_type成员),来调用对应的子格式访存接口。

    由于内容较多,关于磁盘引擎方面的其他内容将在下篇图文中进行分享,敬请期待!

    END

    Gauss松鼠会
    汇集数据库从业人员及爱好者
    互助解决问题 共建数据库技术交流圈
    文章转载自Gauss松鼠会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论