OLTP、OLAP业务各自对数据库的存储引擎提出了不同的要求,而openGauss能够支持多个存储引擎来满足来自不同场景的业务诉求。本章将逐一介绍各种存储引擎和对应的源码。
4.1 存储引擎整体架构及代码概览
从整个数据库服务的组成构架来看,存储引擎向上对接SQL引擎,为SQL引擎提供或接收标准化的数据格式(元组或向量数组);向下对接存储介质,按照特定的数据组织方式,以页面、列存储单元(CU,compression unit)或其他形式为单位,通过存储介质提供的特定接口,对存储介质中的数据完成读、写操作。在此基础之上,存储引擎通过日志系统提供数据的持久化和可靠性能力;通过并发控制(事务)系统保证同时执行的、多个读写操作之间的原子性、一致性和隔离性;通过索引系统提供对特定数据的加速寻址和查询能力;通过主备复制系统提供整个数据库服务的高可用能力。
图4-1 openGauss存储引擎整体构架示意图
图4-1是openGauss存储引擎整体构架的示意图。总体上,根据存储介质和并发控制机制,存储引擎分为磁盘引擎和内存引擎两大类。磁盘引擎主要面向通用的、大容量的业务场景,内存引擎主要面向容量可控的、追求极致性能的业务场景。在磁盘引擎中,为了满足不同业务场景对于数据不同的访问和使用模式,openGauss进一步提供了astore(append-store,追加写优化格式)、cstore(column store,列存储格式)以及可拓展的数据元组和数据页面组织格式。在内存引擎中,openGauss当前提供基于Masstree结构组织的mstore(memory-store,内存优化格式)数据组织格式。
上述几种引擎和存储格式的介绍如表4-1所示。
表4-1 openGauss存储引擎种类
父类 (存储介质和并发控制) |
子类 (数据组织形式) |
说明 |
---|---|---|
磁盘引擎 (磁盘介质, 多版本和悲观并发控制(pessimistic concurrency control,PCC)) |
astore (追加写优化格式) |
主要面向通用的在线交易处理类业务应用场景,适合高并发、小数据量的单点或小范围数据读、写操作。astore为行存储格式,向上提供元组形式的读、写;向下以页面为单位通过可扩展的介质管理器对存储介质进行读、写操作;并通过页面粒度的共享缓冲区来优化读、写操作的效率。当前行存存储格式默认的介质管理器采用磁盘文件系统接口,后续可扩展支持块设备等其他类型的存储介质 |
cstore (列存储格式) |
cstore (列存储格式)
|
面向联机分析处理类业务应用场景,适合大数据量的复杂查询和数据导入。cstore为列存存储格式,向上提供向量数组形式的读、写接口;向下以压缩单元为单位将数据保存在磁盘文件系统中(当前列存存储格式唯一支持的存储介质)。考虑到联机分析处理类业务通常以读操作为主,因此还提供了以压缩单元为粒度的只读共享缓冲区,以加速压缩单元的读操作性能 |
扩展存储格式 |
扩展存储格式 |
对于行存储类存储格式,openGauss提供了与上层SQL引擎对接的、统一的、可扩展的访存接口层(table access method)。该行存储统一访存接口层为SQL引擎提供元组形式的读、写接口,同时屏蔽了下层各种不同行存储类存储格式的内部实现,从而实现了SQL引擎与存储引擎(行存储类磁盘引擎)的解耦,大幅提升了不同存储格式之间的隔离性和开发效率 当前行存储类存储格式支持追加写优化的astore格式,后续会支持更新写优化的ustore格式等其他数据组织格式 |
内存引擎 (内存介质, 乐观并发控制(OCC,optimistic concurrency control)) |
mstore (内存存储格式) |
mstore内存引擎面向超低时延和超高吞吐量的OLTP场景。数据以元组粒度存储于内存介质中,得益于内存介质读、写操作的超低时延(与磁盘介质相比),内存引擎可以提供极致的OLTP业务性能。内存引擎通过openGauss的外表访存接口实现与SQL引擎的数据交互 |
有如下几个特点。
(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
每个子目录都是一个相对独立的模块,和本章内容相关的如表4-2所示。
表4-2 存储引擎子目录
模块名 |
子目录 |
说明 |
---|---|---|
访存模块 |
access子目录 |
主要包括:各种行存储格式中,元组格式;元组与页面之间的转换和访存管理;元组扫描、插入、删除和更新功能的接口实现;几类索引,包括B-Tree、hash、GIN(generalized inverted index,通用倒排索引)、GiST(generalized 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”目录下,简要介绍如表4-3。在后序介绍具体相关模块消息序列时会详细介绍这些线程的工作原理和执行流程。
表4-3 存储引擎后台线程
线程名 |
文件名 |
说明 |
---|---|---|
ADIO线程 |
aiocompleter.cpp |
该线程主要负责异步-同步读写操作(ADIO,asynchronous-direct input-ouput)的后台预取和回写 |
autovacuum线程 |
autovacuum.cpp |
该线程主要负责磁盘引擎的后台空闲空间回收 |
bgwriter线程 |
bgwriter.cpp |
该线程主要负责行存储表的后台脏页写入磁盘(当内存数据页跟磁盘数据页内容不一致的时候,称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”) |
cbmwriter线程 |
cbmwriter.cpp |
该线程主要负责增量页面修改信息的后台异步提取和CBM(changed block map,修改页面位图)日志的记录 |
checkpointer线程 |
checkpointer.cpp |
该线程主要负责在后台定期推进数据库的故障恢复点 |
lwlockmonitor线程 |
lwlockmonitor.cpp |
该线程主要负责业务线程轻量级锁的死锁检测 |
pagewriter线程 |
pagewriter.cpp |
该线程主要负责行存储共享缓冲区的脏页写入磁盘 |
pgarch线程 |
pgarch.cpp |
该线程主要负责在后台定期执行日志归档命令 |
remoteservice线程 |
remoteservice.cpp |
该线程主要负责接收主机页面修复RPC(remote procedure call,远程函数调用)请求 |
startup线程 |
startup.cpp |
该线程为数据库故障恢复和回放日志的主线程 |
walwriter线程 |
walwriter.cpp |
该线程主要负责在后台异步写入磁盘日志 |
4.2 磁盘引擎
磁盘引擎是数据库系统中最常用的存储引擎,openGauss提供不同存储格式的磁盘引擎来支持大容量(数据量大于内存空间)场景下的OLTP、OLAP和HTAP(hybrid transactions and analytics processing,混合交易和分析处理)业务。本节主要介绍openGauss数据库内核中磁盘引擎的实现方式。
4.2.1 磁盘引擎整体框架及代码概览
磁盘引擎的整体框架如图4-1中所示。根据与上层SQL引擎之间交互的数据结构类型,可以分为行存储格式和列存储格式。这两种数据格式共用相同的事务并发控制、日志系统、持久化和故障恢复、主备系统。
在此基础之上,行存储格式内部设计为可以支持多种不同子格式的可扩展架构。不同行存储子格式之间共用相同的行存储统一访存接口(table access method)、共享缓冲区、索引机制等。当前仅支持追加写优化的astore子格式,后续计划支持写优化的ustore子格式以及面向其他场景优化的其他子格式。另一方面,在openGauss行存储格式中,对同一行数据的写-写查询冲突通过两阶段锁协议来实现并发控制(参见第5章中关于行级锁的介绍),对同一行数据的读-写查询冲突通过行级多版本技术来实现互不阻塞的、高效的并发控制。对于不同的行存储子格式,可能采用不同的行级多版本实现方式,从而也会引入不同的、清理历史版本的空闲空间管理和回收机制。
磁盘引擎的主要功能模块和代码分布如表4-4所示。
表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堆表/索引表元组在页面内的具体组织形式,在页面内插入元组操作、页面整理操作、页面初始化、页面加解密、页面CRC(cyclic 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列存储表CU间、CU内结构,完成对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章单独介绍 |
事务提交日志SLRU(Simple 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开销。
4.2.2 行存储统一访存接口
如上所述,在openGauss中,提供行存储统一访存接口层,来屏蔽不同行存储子格式内部实现机制对SQL引擎的影响。该行存储统一访存接口层被称为Table Access Method层。根据SQL引擎对行存储表的访存方式,将访存接口分为5类,如表4-5所示。每一类接口的具体操作如表4-6至4-10所示。
表4-5 Table Access Method定义的访存接口
接口类别 |
接口含义 |
---|---|
Tuple AM Slot AM |
元组(tuple)和元组槽(slot)操作抽象层,包括元组数据结构的抽象、元组操作的抽象,执行引擎无须关注元组属于哪种行存储子格式,只需调用元组数据结构基类的抽象操作接口,就可操作不同行存储子格式的元组,从而屏蔽不同行存储子格式物理元组结构、访问方法的差异 |
TableScan AM |
表扫描(table scan)抽象层,包括TableScan数据结构的抽象、TableScan管理操作的抽象,执行引擎无须关注行存储子格式内部TableScan结构的差异,通过调用TableScan数据结构基类的抽象管理接口,就可完成不同行存储子格式的TableScan管理,屏蔽不同行存储子格式内部实现的差异 |
DQL AM |
元组查询(data query language,DQL)操作抽象层,包括获取元组、元组可见性判断等查询操作的抽象 |
DML AM |
元组写操作抽象层,包括元组插入、批插、删除、更新、锁定等接口的抽象 |
DDL AM |
表物理操作抽象层,这里统称为DDL抽象层,涉及表物理文件操作的相关接口的抽象,例如CTAS、TRUNCATE、LOAD/COPY、VACUUM、VACUUM FULL、ANALYZE、REBUILD INDEX、ALTER TABLE RESTRUCT等DDL语法。该层也可以支持存储管理的抽象功能,如屏蔽不同行存储子格式的文件/目录管理模块、SMGR访问等差异 |
表4-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 |
返回slot中minimal tuple的副本,该副本在当前内存上下文中被分配,需要调用者进行释放操作 |
tableam_tslot_store_minimal_tuple |
此函数在指定的TupleTableSlot结构体中存储minimal tuple |
tableam_tslot_get_heap_tuple |
该函数获取slot中的tuple |
tableam_tslot_copy_heap_tuple |
该函数返回slot中tuple的副本,该副本在当前内存上下文中被分配,需要调用者进行释放操作 |
tableam_tslot_store_tuple |
该方法将对应的物理元组存储到slot中 |
tableam_tslot_getsomeattrs |
强制更新slot中tuple某个属性的values和isnull数组信息 |
tableam_tslot_getattr |
获取当前slot中tuple的某个属性信息 |
tableam_tslot_getallattrs |
强制更新slot中tuple的values和isnull数组 |
tableam_tslot_attisnull |
检查slot中tuple的属性是否为null |
tableam_tslot_get_tuple_from_slot |
从slot中获取一个tuple,并根据relation结构体中行存储子格式信息转换为对应子格式的tuple |
tableam_tops_getsysattr |
获取tuple的系统属性 |
tableam_tops_form_minimal_tuple |
根据values和isnull数组内容,新建一个tuple |
tableam_tops_form_tuple |
根据values和isnull数组内容,新建一个minimal tuple |
tableam_tops_form_cmprs_tuple |
根据values和isnull数组内容,新建一个被压缩的tuple |
tableam_tops_deform_tuple |
抽取指定tuple中的data数据到values和isnull数组 |
tableam_tops_deform_cmprs_tuple |
抽取被压缩的tuple中的data数据到values和isnull数组 |
tableam_tops_computedatasize_tuple |
计算需要构造的tuple的data区域的大小 |
tableam_tops_fill_tuple |
根据values和isnull数组中的数据填充到tuple的data区域 |
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 |
表4-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(顺序扫描) |
表4-8 DQL AM类访存接口
接口名称 |
接口含义 |
---|---|
tableam_tuple_fetch |
根据tid(元组物理位置)获取tuple |
tableam_tuple_satisfies_snapshot |
指定元组对于快照是否可见 |
tableam_tuple_get_latest_tid |
获取tid指向的当前snapshot(快照)可见的最新物理元组 |
表4-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操作的尝试插入操作,转为更新操作 |
表4-10 DDL AM类访存接口
接口名称 |
接口含义 |
---|---|
tableam_index_build_scan |
该方法用于创建索引的首次全表扫描 |
tableam_index_validate_scan |
该方法用于并发创建索引的第二次全表扫描 |
tableam_relation_copy_for_cluster |
将源表数据根据指定的聚簇方式复制到新表中 |
对于每一个行存储子格式,需要提供上述这五类访存接口的各自实现方式,并注册到g_tableam_routines全局行存储访存接口数组中。SQL引擎在调用某个访存接口时,根据Relation结构体中表的子格式类型(rd_tam_type成员),来调用对应的子格式访存接口。
由于内容较多,下篇我们将详细介绍“4.2.3 astore”相关内容,敬请期待!