前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >PG通过表访问方法API如何执行顺序扫描

PG通过表访问方法API如何执行顺序扫描

作者头像
yzsDBA
发布于 2021-02-03 04:05:13
发布于 2021-02-03 04:05:13
1.3K0
举报

PG通过表访问方法API如何执行顺序扫描

引言

PG中有很多方法检索数据并返回给用户。依赖于用户的SQL语句,查询计划模块生成最有方法以检索请求的数据。顺序扫描是用户请求大量数据时或者当表没有索引时使用的一种检索方法(例如select * from tablename;);顺序扫描方法由表的表访问方法APIchuli,heap表访问方法时当前版本中默认的方法。本文中,将会介绍表访问方法API如何进行顺序扫描。

PG中表访问方法APIs

PG12中引入了可拔插表访问方法,允许开发者重定义存储/检索表数据的方法。这个API包含42个函数。定义在tableam.h中,这些接口函数在typedef struct TableAmRoutine中。下面介绍关于顺序扫描的routine,帮助开发这了解如何创建自己的表访问方法。

顺序扫描的调用栈

42个routines中很少由一个会被执行器调用来完成顺序扫描的请求。本节按调用顺序描述这些接口。

relation_size

函数声明:uint64 (*relation_size) (Relation rel, ForkNumberforkNumber);

Relation_size函数是第一个被调用的函数,相对简单。通过rel和forkNumber,返回对于文件的大学。默认heap表访问方法会调用存储管理器smgr,计算出对于表文件的页数,然后成语每个页大小BLCKSZ默认8KB。如果不确定表和forknumber之间的关系,可以查询网址https://www.highgo.ca/2020/10/23/free-space-mapping-file-in-details/了解更多信息。

返回的大小设置顺序扫描的边界。

slot_callbacks

函数声明:const TupleTableSlotOps*(*slot_callbacks) (Relation rel);

下一步,执行器需要找出此表访问方法与哪一个tuple table slot(TTS)回调操作的集合兼容。TTS是routines集合,确保tuple存储在执行器和访问方法之间兼容。执行器执行TTS回调以TupleTableSlot结构传输tuple,该结构执行器可以认识。默认的heap访问方法使用execTuples.c中定义的TTSOpsBufferHeapTuple来处理这个操作。

scan_begin

函数声明:TableScanDesc (*scan_begin) (Relationrel,

Snapshotsnapshot,

int nkeys,struct ScanKeyData *key,

ParallelTableScanDesc pscan,

uint32flags);

现在可以开始扫描。这个函数是顺序扫描的初始化函数,将使用执行器传输的参数分配一个新的scan描述符。Scan描述符结构的目的在于执行顺序扫描时进行跟踪。例如,要跟踪从哪里开始扫描,上次扫描块号是什么时候,应该回复扫描哪个块,以及扫描了多少块等等。一旦顺序扫描完成,scan描述符会被销毁。

执行器希望接口返回指向TableScanDesc结构的指针。

scan_getnextslot

函数声明:bool (*scan_getnextslot) (TableScanDescscan,

ScanDirection direction,

TupleTableSlot *slot);

这个函数是顺序扫描的主要函数,从buffer管理器中获取一个tuple,转换成TTS格式并将它存储到slot指针中。每次调用返回一个tuple。如果表由1000个tuple,这个函数会调用1000次。返回true表示需要再次调用获取下一个tuple,返回false表示获取了所有元组,不用再调用这个函数了。

通常情况下顺序扫描以per-page模式进行工作。也就是说从buffer管理器中加载并读入一个block到内存,然后从这个页中一个元组一个元组地进行返回,获取完一页,再加载另一页进行扫描。

Scan描述符起着重要作用,因为这个结构体中存有大量控制信息,调用scan_getnextslot会更新。

scan_end

函数声明:void (*scan_end) (TableScanDesc scan);

顺序扫描调用的最后一个函数,用于清理scan描述符。此时执行器已经通过顺序扫描方法获取了所有元组信息。

准备返回的数据

现在执行器通过表访问方法扫描了所有元组,需要进入过滤流程决定哪些元组符合返回的条件(例如使用WHERE限制扫描结果)。由execScan.c中的for循环在每个TTS上执行ExecQual,最终结果发送给用户。

总结

流程图如下:

原文

https://www.highgo.ca/2021/01/15/how-postgresql-executes-sequential-scans-with-the-help-of-table-access-methods-apis/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yanzongshuaiDBA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Postgresql源码(76)执行器专用元组格式TupleTableSlot
执行器对元组格式的要求非常灵活,例如select 1;表达式结果、select a,b,c from t;投影临时结果等等。
mingjie
2022/09/26
9490
Postgresql源码(76)执行器专用元组格式TupleTableSlot
PgSQL-内核特性-TupleTableSlotOps
执行器中表达式结果、函数结果、投影结果等,各种结果都需要以元组的形式返回,所以PgSQL引入了一种通用格式保存数据:TupleTableSlot。PgSQL执行器将记录存储到“元组表”中在各个算子之间进行传递,元组表是独立TupleTableSlot的链表。而TupleTableSlot又分为多种,以减少解析和构建开销。
yzsDBA
2023/10/04
5150
PgSQL-内核特性-TupleTableSlotOps
PostgreSQL TID及tuple slot
1)postgresql默认存储的是堆表,数据按行存储在heap page中。行记录除了存储字段的值外还会存储对应的ctid即行号,表示在哪个页第几个记录。
yzsDBA
2020/02/19
2.2K0
PostgreSQL TID及tuple slot
PgSQL - 内核插件 - pg_dirtyread
表中删除了记录,并且没有进行vacuum,此时可以通过pg_dirtyread扩展读取死记录。
yzsDBA
2024/04/12
2400
PgSQL - 内核插件 - pg_dirtyread
Postgresql源码(64)查询执行——子模块Executor(2)执行前的数据结构和执行过程
上一篇说明了执行的框架,本篇深入分析执行细节。测试用例不变,还是分析之前的case。
mingjie
2022/08/03
6990
Postgresql源码(64)查询执行——子模块Executor(2)执行前的数据结构和执行过程
Postgresql源码(55)IndexOnlyScan读取vm信息跳过扫描堆表,为什么读取vm可以不加锁?
导读1:这篇比较有意思,代码不多但是并发场景需要一定的分析,这里尝试分析并记录下背景和结果。 导读2:IndexOnlyScan访问vm页面判断如果页面的可见性为VM_ALL_VISIBLE,那么可以直接使用索引数据返回,不必去读堆页面。但是访问vm页面时没有加锁,如果出现race condition有人在并发修改vm会不会出现问题?
mingjie
2022/06/15
4380
PgSQL - 内核特性 - 把DuckDB弄进来怎么样
DuckDB是一款高性能的分析型数据库系统,支持了基于Push-based pipeline的向量化执行引擎。这么好的一款数据库,有办法直接弄到PgSQL里面,以利用其优秀的列式存储、向量化执行引擎等优秀特性吗?Hydra团队开源了一款插件pg_quack,将duckdb以表访问方法的方式加到PgSQL中,为PgSQL提供了新的存储引擎以及执行引擎。
yzsDBA
2024/03/02
6590
PgSQL - 内核特性 - 把DuckDB弄进来怎么样
Postgresql查询执行模块README笔记
每个节点在被调用时将在其输出序列中生成下一个元组,如果没有更多的元组可用,则为 NULL。
mingjie
2022/09/26
1.1K0
Postgresql查询执行模块README笔记
存储的未来
对于某些用例,当前存储设计是次优的。我们相信可以通过在”heap”操作和存储之间添加一个抽象层来进行改进。当前,存储设计基于按行组织页的假设:heapam.h假设:每个tuple只有一个元组头和一个数据区域,即包括HeapTuple及tuple逻辑操作的代码,比如delete、update、加锁。类似,执行器代码表示TupleTableSlot抽象层的元组,该抽象层下面是HeapTuple。2015年2ndQuadrant致力于在PG中实施列式存储项目,以下是根据实施过程中吸取的经验得出的计划。
yzsDBA
2022/02/09
6720
PostgreSQL TID及tuple slot
1)postgresql默认存储的是堆表,数据按行存储在heap page中。行记录除了存储字段的值外还会存储对应的ctid即行号,表示在哪个页第几个记录。
yzsDBA
2020/10/28
8170
PostgreSQL TID及tuple slot
PostgreSQL可拔插存储引擎表定义机制
Postgresql12开始支持可拔插存储引擎,即可拔插表访问方法。目前仅仅支持heap一种表访问方法。新增了pg_am和pg_proc系统表用于存储表访问方法的元数据。本文介绍创建表时如何处理这些元数据。
yzsDBA
2020/10/28
1.4K0
PostgreSQL可拔插存储引擎表定义机制
Postgresql源码(107)analyze行采样流程分析(pg_class中reltuples行数评估是哪里来的准确吗)
注意函数中bs->n = samplesize;会记录30000页面数,后续BlockSampler_Next函数在生成采样页面ID时,如果页面总数小于30000,就不随机了,按顺序遍历所有页面就好了。
mingjie
2023/10/13
3100
Postgresql源码(107)analyze行采样流程分析(pg_class中reltuples行数评估是哪里来的准确吗)
Postgresql源码(88)简单复习HOT更新流程
update t8 set info='87b5696b76a041a41495da0000000000' where id = 149370;
mingjie
2022/11/16
6470
Postgresql源码(88)简单复习HOT更新流程
Postgresql源码(129)JIT函数中如何使用PG的类型llvmjit_types
llvmjit_types.c里面定义了一些类型的变量,这些变量的bitcode在初始化时(llvm_create_types),会加载到module中(llvm_types_module)。然后再通过llvm_pg_var_type函数,把类型读取出来保存到全局变量中:
mingjie
2024/05/24
1600
PostgreSQL表扫描方法解析
全表扫描函数在heapam_handler的接口函数为heap_getnextslot函数。该函数从磁盘上读取数据页到内存并将遍历页记录,将其存放到slot中返回。这个函数一次只获取一个记录,到达上层的ExecutePlan函数中循环调用ExecProcNode再次进入到heap_getnextslot函数获取下一个记录,依次类推,直到获得所有记录。
yzsDBA
2020/10/28
1.2K0
PostgreSQL表扫描方法解析
Postgresql源码(83)执行器的结果接收系统——DestReceiver
执行器的工作包括:work、get result,之前work的内容已经介绍过了,这里分析下执行器如何拿到执行结果。
mingjie
2022/09/30
8820
列存zedstore
简单说,忽略列存储概念,将之认为压缩的行存储。列存储是这个概念的扩展,在下节解释。最基本的磁盘数据结构是B-tree,以TID为索引列。注意,这不是现有的Btree索引,而是独立于表数据存储的另外新Btree。
yzsDBA
2020/10/28
2.1K0
PG 向量化引擎--1
向量化引擎是OLAP数据库提升性能的有效技术。翻到PostgreSQL邮件列表有对向量化引擎的讨论。这里进行整理,以作分析。
yzsDBA
2022/02/09
1.4K0
深度 | 如何玩转PG查询处理与执行器算法
作者介绍 孙旭,腾讯云高级工程师。10年数据库内核研发经验,熟悉PostgreSQL、Teradata数据库内核,熟悉数据库的查询优化、执行、事务并发以及存储等子系统;对分布式数据库有深入的研究和研发经验。目前在腾讯云从事CynosDB数据库研发工作。 一、导语 数据库查询处理(Query Processing)是数据库比较核心的技术,也是距离用户最近的子系统。数据库系统在除了实现事务的隔离界别外,还需要在SQL上做到一定程度的兼容,因为数据库本身就是在做查询处理,很多的内核模块工作都是为了支持这个功能
腾讯云数据库 TencentDB
2019/10/17
2.3K0
深度 | 如何玩转PG查询处理与执行器算法
GPDB7-新特性-Fast ANALYZE on Append-Optimized tables
GPDB7-新特性-Fast ANALYZE on Append-Optimized tables
yzsDBA
2023/10/23
2250
GPDB7-新特性-Fast ANALYZE on Append-Optimized tables
相关推荐
Postgresql源码(76)执行器专用元组格式TupleTableSlot
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档