数据库内核分析之GPDB and PostgreSQL Portal
GPDB and 数据PostgreSQL Portal内核分析
0.导论
Portal(门户),也称为策略选择模块,库内根据sql语句类型选择不同的核分执行模块(ProcessUtility、Executor)。数据
SQL语句类型包括:可优化语句、库内数据定义语句。核分
可优化语句包括DML,数据像insert/update/select等语句,库内这类语句特点是核分查询满足条件的元组返回给用户或者元组操作后写入磁盘,之所以称之为可优化语句是数据因为这类语句通常会被优化器进行重写与优化,从而加快查询速度。库内
数据定义语句主要是核分功能性语句,例如:DDL(Create、数据Alter、库内Drop)、核分DCL(Grant、COMMIT、ROLLBACK)等。

1.Portal
1.1 入口层QD执行会从exec_simple_query进入,QE执行从exec_mpp_query进入。
1.2 Portal层1.2.1 初识Portal
首先初识Portal内部数据结构:

策略只包含一个SELECT查询。
复制select * from t1;1.包含一个INSERT/UPDATE/DELETE查询,且带RETURNING条件。
复制INSERT INTO ret_tbl (id) VALUES (3) RETURNING id INTO tableId;1.包含一个SELECT查询并且有修改的CTE。
复制WITH ins AS ( INSERT INTO t1 (t1_id) VALUES(1)RETURNING t1_id
)SELECT * from ins;1.2.3.4.例如:下面这个就不是PORTAL_ONE_MOD_WITH,而是PORTAL_MULTI_QUERY。站群服务器
复制WITH ins AS (
SELECT * from t1
) INSERT INTO t2
(t2_id, col2)
SELECT * from ins;1.2.3.4.5.包含一个utility语句,且该语句执行会返回像SELECT那样有输出结果。
复制postgres=# explain select * from t1;QUERY PLAN
------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=12) Optimizer: Pivotal Optimizer (GPORCA)(3 rows)postgres=# EXECUTE t1_fn_ret(2, helloworld); t1_id |col1
-------+------------ 2 |helloworld
(1 row)INSERT 0 11.2.3.4.5.6.7.8.9.10.11.12.13.14.15.其他情况,例如:PORTAL_MULTI_QUERY + PORTAL_MULTI_QUERY
复制PREPARE t1_fn (int, text) AS INSERT INTO t1 VALUES($1, $2);1. PORTAL_MULTI_QUERYPORTAL_UTIL_SELECTPORTAL_ONE_MOD_WITHPORTAL_ONE_RETURNINGPORTAL_ONE_SELECT状态
PORTAL_NEWPORTAL_DEFINEDPORTAL_READYPORTAL_QUEUEPORTAL_ACTIVEPORTAL_DONEPORTAL_FAILED这几个状态会在下面依次引入。
1.2.2 CreatePortal
创建一个新的Portal,传入参数均为: CreatePortal("", true, true),表示创建一个匿名的Portal,允许重复且重复后保持沉默。
CreatePortal逻辑:
复制Portal
CreatePortal(const char *name, bool allowDup, bool dupSilent)1.2. 根据传入的第一个参数name从哈希表中查找根据传入的第二个参数allowDup,如果第一步查找到,从哈希表中决定是否删除。如果true,则删除,否则报错。在哈希表中查找到Portal且允许重复的情况下,在QD节点上会根据第三个参数dupSilent决定是否输出告警信息。创建一个新的Portal,并初始化相应参数。执行完毕后,便创建好了一个状态为PORTAL_NEW的Portal。
1.2.3 PortalDefineQuery
定义portal数据,包含了:查询语句sourceText、PlannedStmts、查询完成标记qc。免费源码下载
注意:QD上根据传递进来的stmt来设置nodeTag,但是QE上为T_Query,因为QE上不是parsed statement,所以不是 T_SelectStmt。
最终设置Portal状态为PORTAL_DEFINED。
1.2.4 PortalStart
准备好portal,主要有如下几步:
设置ddesc,该信息为QD到QE上的额外信息,QD上为NULL,QE上不为NULL。设置全局参数,例如:当前活跃的portal、resourceOwner、context。设置portal参数字段:portalParams,同样QD上为NULL,QE上不为NULL。设置portal策略(ChoosePortalStrategy)。如下图所示:输入为查询计划链表,针对PORTAL_ONE_SELECT、PORTAL_ONE_MOD_WITH、PORTAL_UTIL_SELECT、PORTAL_ONE_RETURNING都是要求一个计划,首先判断是Query还是PlannedStmt,源码库一般情况下的查询语句基本都是PlannedStmt,对于像PREPARE st(int) as select * from t1之类utility语句第一次调用ChoosePortalStrategy返回PORTAL_MULTI_QUERY(命中PlannedStmt),第二次调用返回PORTAL_ONE_SELECT(命中Query)。

choose
5. 根据portal策略初始化portal,最重要的是初始化tupDesc与cursor postion。

例如:"QUERY PLAN"、"t1_id、col1"就是tupDesc。
复制postgres=# explain select * from t1;QUERY PLAN
------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=12) Optimizer: Pivotal Optimizer (GPORCA)(3 rows)postgres=# EXECUTE t1_fn_ret(2, helloworld); t1_id |col1
-------+------------ 2 |helloworld
(1 row)INSERT 0 11.2.3.4.5.6.7.8.9.10.11.12.13.14.15.不同tupleDesc函数区别
ExecTypeFromTLskip resjunk column
ExecCleanTypeFromTLwith resjunk column
6. 在执行Portal过程中发生异常,设置portal的状态为PORTAL_FAILED;否则,下一步。
7. 设置Portal状态为PORTAL_READY。
1.2.5 PortalRun根据sql的语句类型选择不同的执行路径,获取元组数据,完成portal工作,运行完之后要么Done要么下一轮(READY,而非ACTIVE)。
portal策略执行路径如下:
PORTAL_ONE_SELECTset result = portal->atEnd
PORTAL_ONE_RETURNING|PORTAL_ONE_MOD_WITH|PORTAL_UTIL_SELECT获取时数据方向包含前进/后退
可以从holdStore中获取,也可以从ExectorRun中获取
填充holdStore(见下方)
调用PortalRunSelect返回n行数据
设置状态为PORTAL_READY
设置是否完成运行标记为portal->atEnd
PORTAL_MULTI_QUERY调用PortalRunMulti
设置状态为PORTAL_Done
设置是否完成运行标记为true

此外,上述图中填充holdStore逻辑如下:
调用PortalCreateHoldStore填充portal->holdStore,通过工厂函数CreateDestReceiver构造DestReceiver(子类:TStoreState);根据portal策略执行查询:PORTAL_ONE_RETURNING、PORTAL_ONE_MOD_WITH 调用PortalRunMulti,PORTAL_UTIL_SELECT调用PortalRunUtility。PortalRunUtility
PortalRunMulti
ProcessQuery
PortalRunUtility
utilityStmt
not utilityStmt
PORTAL_ONE_RETURNING、PORTAL_ONE_MOD_WITH
PORTAL_UTIL_SELECT

2.游标Cursor
2.1 打开游标如果不想一次执行整个命令,可以设置一个封装该命令的游标(cursor), 然后每次读取几行命令结果。
复制name [ [ NO ] SCROLL ] CURSOR [ ( arguments ) ] FOR query;1.例如:
复制DECLARE liahona SCROLL CURSOR FOR SELECT * FROM t1;1.该命令运行机制为:首先识别到是一个数据定义语句,便会调用ProcessUtility,随后解析从PlannedStmt中的utilityStmt识别出是一个T_DeclareCursorStmt节点,调用PerformCursorOpen执行Declare cursor命令。
PerformCursorOpen处理逻辑如下:
query重写优化器优化,生成PlannedStmt创建Portal(名字为游标名),仅调用PortalStart2.2 关闭游标关闭游标,实际就是关闭Portal,调用PerformPortalClose。
如下两个操作:
复制CLOSE cursor_name;CLOSE ALL;1.2.如果传入的名字为空,则是CLOSE ALL关闭所有非活跃portal,否则,只关闭指定的portal(cursor)。
2.3 FETCH or MOVEFETCH与MOVE语法分别如下:
复制FETCH [ direction { FROM | IN } ] cursor INTO target;
MOVE [ direction { FROM | IN } ] cursor;1.2.FETCH从游标中检索n行到目标中, 目标可以是一个行变量、记录变量、逗号分隔的普通变量列表, 就像SELECT INTO一样, 如果没有获取到数据,目标会设为NULL。
MOVE重新定位一个游标,而不需要检索任何数据,例如:一旦游标位置确定,则可以删除或更新行。
复制MOVE cursor_variable;UPDATEtable_name
SET column = value,...
WHERE CURRENT OF cursor_variable;1.2.3.4.从实现层面两者都会进入到PerformPortalFetch,都被解析为FetchStmt,内部有个成员ismove决定是MOVE还是FETCH。
不管是哪个,都会指定cursor名,有了这个名字,便知道了portal,随后调用PortalRunFetch来获取结果。
PortalRunFetch内部会像PortalRun运行一样,首先设置portal状态为Active,随后根据策略选择不同的调用链。
PORTAL_ONE_SELECT调用DoPortalRunFetch
PORTAL_ONE_RETURNING|PORTAL_ONE_MOD_WITH|PORTAL_UTIL_SELECT首先判断portal内部是否有holdStore,如果没有会调用FillPortalStore,随后调用DoPortalRunFetch。
DoPortalRunFetch内部实现,会考虑传入的direction,决定是前向还是后向等不同方向的扫描,最后调用PortalRunSelect获取数据,注意:gpdb不支持backward scan,但是pg支持。

相关文章
台式电脑SSD装机教程(从零开始,教你轻松完成台式电脑SSD的安装和配置)
摘要:随着科技的不断发展,SSD固态硬盘)已经逐渐取代了传统的机械硬盘,成为了许多电脑用户升级的首选。本文将为大家介绍如何将SSD安装到台式电脑中,并简单配置以提升性能,让您的电脑焕发...2025-11-05
AMD 以全新第二代 Versal 系列器件扩展领先自适应 SoC 产品组合,为 AI 驱动型嵌入式系统提供端到端加速
2024 年 4 月 9 日,德国纽伦堡国际嵌入式展)——AMD今日宣布扩展 AMD Versal™ 自适应片上系统 SoC )产品组合,推出全新第二代 Versal AI Edge 系列和第二代 V2025-11-05
你是一个程序员,前后端是你,运维还是你。公司有一批云服务器,上面部署了视频推荐,语音识别,前端网页等各种应用服务。你经常要手动将应用服务挨个部署到各个服务器上,服务器出问题了,还得跑到别的服务器上手动2025-11-05VMware“地震级”剧变,大量VM独立产品被放弃!用户:是时候考虑替代品了
编译 | 言征出品 | 51CTO技术栈微信号:blog51cto)25年以来,VMware,可谓名利双收。然而就在去年11月,博通斥巨资690亿美元收购后,不到1个月,就下定决心快刀斩乱麻:终止永久2025-11-05三星9100使用移动卡上网的网速如何?(以三星9100为例,探讨移动卡上网的速度表现及使用体验。)
摘要:移动网络已经成为我们日常生活中不可或缺的一部分,而移动设备的网速表现也直接影响了我们的上网体验。本文将以三星9100为例,探讨其在使用移动卡上网时的网速情况。三星9100使...2025-11-05
英特尔 ®至强 ®品牌新战略发布 携至强®6处理器满足计算产业新需求
品牌是企业使命和发展的象征,也承载着产品特质和市场认可。今天,在英特尔GTC科技体验中心的英特尔® 至强® 6 能效核处理器发布会上,英特尔公司全球副总裁兼首席市场营销官Brett Hannath宣布2025-11-05

最新评论