【PostgreSQL内核学习(二十二)—— 执行器(ExecutePlan)】

执行器(InitPlan)

  • 概述
  • ExecutePlan 函数
    • ExecProcNode 函数
  • 总结

声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。
本文主要参考了 postgresql-10.1 的开源代码和《OpenGauss数据库源码解析》和《PostgresSQL数据库内核分析》一书

概述

  在文章【OpenGauss源码学习 —— 执行器(execMain)】中,我们深入探究了执行器在数据库中的核心功能和逻辑。这篇文章详细介绍了执行器的主要组成部分,如查询执行的初始化与结束主执行循环、以及行处理逻辑等。通过这篇文章,读者可以了解到执行器是如何在数据库系统中处理用户的查询请求,包括如何遍历执行树执行计划节点,以及如何对数据进行操作和传递
  另一方面,文章【PostgreSQL内核学习(二十一)—— 执行器(InitPlan)】则专注于介绍了 InitPlan 函数在 PostgreSQL 数据库中的作用。这篇文章详细阐述了 InitPlan 如何初始化查询计划,设置执行状态,以及如何准备查询执行所需的各种资源和环境。读者可以通过这篇文章深入理解 InitPlan 在查询执行过程中的重要性,以及它是如何为高效执行查询提供支持的。
  本文将深入了解 ExecutePlan原理实现细节,从而更好地理解数据库查询的执行机制。具体学习的模块如下图红色框体所示:
在这里插入图片描述

ExecutePlan 函数

  ExecutePlan 函数是数据库查询执行过程中的核心部分,负责按照给定的方向处理查询计划,并从中检索指定数量的元组。函数首先初始化一些本地变量,包括当前处理的元组数量执行方向。它还处理查询计划的并行执行模式,根据执行条件启用或禁用并行模式。
  函数的主体是一个无限循环,它反复执行查询计划的节点,直到满足某个退出条件。在每次循环中,它首先重置表达式上下文,然后执行计划节点来获取一个元组。如果获取的元组为空,表示没有更多数据要处理,因此它将结束循环。此外,如果存在垃圾过滤器,函数将对元组进行处理以移除不需要的数据。
  如果设置为发送元组,函数将尝试将元组发送到指定的目的地。如果发送失败(可能因为目的地已关闭),循环也会结束。对于 SELECT 操作,函数还会统计处理的元组数量。如果达到了指定的元组数量numberTuples),或者如果没有指定数量numberTuples0),表示处理全部元组,循环也将结束。
  总之,ExecutePlan 函数的主要作用是根据查询计划执行数据库查询,处理和发送检索到的数据,同时在满足特定条件时结束处理。这个函数是数据库查询执行过程中的关键环节,确保了查询按照预定的方式进行,且能够有效地处理和返回所需数据。函数源码如下所示:(路径:src\backend\executor\execMain.c

/* ----------------------------------------------------------------*		ExecutePlan**		根据指定的方向处理查询计划,直到检索到 'numberTuples' 个元组。**		如果 numberTuples 为 0,则运行到完成。** 注意:ctid 属性是一个“垃圾”属性,在用户看到之前会被移除。* ----------------------------------------------------------------*/
static void
ExecutePlan(EState *estate,PlanState *planstate,bool use_parallel_mode,CmdType operation,bool sendTuples,uint64 numberTuples,ScanDirection direction,DestReceiver *dest,bool execute_once)
{TupleTableSlot *slot; // 声明一个元组槽,用于存储当前处理的元组uint64 current_tuple_count; // 当前已处理元组的计数/* 初始化局部变量 */current_tuple_count = 0;/* 设置执行方向 */estate->es_direction = direction;/* * 如果计划可能会被多次执行,必须禁用并行模式,因为我们* 可能会提前退出。另外,在写入关系(如更新表格)时也禁用并行模式,* 因为在并行模式下不允许数据库更改。*/if (!execute_once || dest->mydest == DestIntoRel)use_parallel_mode = false;estate->es_use_parallel_mode = use_parallel_mode; // 设置是否使用并行模式if (use_parallel_mode)EnterParallelMode(); // 如果使用并行模式,则进入并行模式/* 循环执行计划,直到处理了指定数量的元组 */for (;;){/* 重置每个输出元组的表达式上下文 */ResetPerTupleExprContext(estate);/* 执行计划并获取一个元组 */slot = ExecProcNode(planstate);/* 如果元组为空,假定没有更多内容要处理,结束循环 */if (TupIsNull(slot)){/* 允许节点释放或关闭资源 */(void) ExecShutdownNode(planstate);break;}/* 如果有垃圾过滤器,那么生成一个新元组,并移除垃圾 */if (estate->es_junkFilter != NULL)slot = ExecFilterJunk(estate->es_junkFilter, slot);/* 如果需要将元组发送到某处,则进行发送 */if (sendTuples){/* 如果无法发送元组,假定目的地已关闭,无法发送更多元组,结束循环 */if (!((*dest->receiveSlot) (slot, dest)))break;}/* 如果是 SELECT 操作,计算处理的元组数。(对于其他操作类型,ModifyTable 计划节点必须计算相应的事件。)*/if (operation == CMD_SELECT)(estate->es_processed)++;/* 检查处理的元组数量。如果达到了指定数量,则退出;如果 numberTuples 为零,则表示没有限制 */current_tuple_count++;if (numberTuples && numberTuples == current_tuple_count){/* 允许节点释放或关闭资源 */(void) ExecShutdownNode(planstate);break;}}/* 如果使用了并行模式,退出并行模式 */if (use_parallel_mode)ExitParallelMode();
}

ExecProcNode 函数

  ExecProcNode 函数是数据库查询执行过程中的一个关键部分,用于执行给定的计划节点(PlanState)并返回一个元组(TupleTableSlot
  ExecProcNode 函数的作用是执行查询计划树中的一个特定节点,并从这个节点获取一个元组。这个函数是数据库查询执行的核心组成部分,因为它直接涉及到从计划节点获取数据的过程。

  • 检查节点参数变化函数首先检查 node->chgParam,这是一个标志,表明节点的参数是否发生了变化。如果这个标志不为空,意味着节点的一些执行参数已经改变,需要重新扫描(re-scan)。这通常发生在查询执行过程中,某些外部条件或者上游节点的输出发生变化时。
  • 重新扫描如果检测到参数变化,函数将调用 ExecReScan 来重新设置节点的状态,以便正确反映新的参数或环境。
  • 执行节点并获取元组最后,函数调用节点自身的 ExecProcNode 方法来执行该节点的逻辑,并获取下一个可用的元组。不同类型的节点(如扫描节点连接节点等)将有其特定的 ExecProcNode 实现,以执行相应的数据检索或处理逻辑。

  总结来说,ExecProcNode 是数据库查询执行流程中的核心函数之一,负责直接从查询计划的特定节点获取数据。这个函数通过动态执行计划节点的特定逻辑,使得整个查询过程可以根据计划逐步进行,同时能够适应查询执行过程中可能出现的变化,确保数据的正确检索和处理。函数源码如下所示:(路径:src\include\executor\executor.h

/* ----------------------------------------------------------------*      ExecProcNode**      执行给定的节点以返回一个(或另一个)元组。* ----------------------------------------------------------------*/
#ifndef FRONTEND
static inline TupleTableSlot *
ExecProcNode(PlanState *node)
{/* 如果节点的参数有所改变 */if (node->chgParam != NULL) /* 发生了一些变化? */ExecReScan(node);       /* 让 ReScan 函数处理这种情况 *//* 执行节点的 ExecProcNode 方法并返回一个元组 */return node->ExecProcNode(node);
}
#endif

  注: ExecProcNode 函数用于执行给定的计划节点,并返回一个元组TupleTableSlot),它是该节点执行的结果。计划节点可以包括顶层查询计划节点,也可以包括子查询的计划节点,每个节点都有一个相应的 ExecProcNode 函数来执行它。这里,代码node->ExecProcNode(node);是在 InitPlan 时,根据所执行算子的具体类型来进行赋值的。例如以 ExecInitResult 函数为例,如下代码段所示:

	/** create state structure*/resstate = makeNode(ResultState);resstate->ps.plan = (Plan *) node;resstate->ps.state = estate;resstate->ps.ExecProcNode = ExecResult;

  所以,“给定的计划节点” 意味着你想要执行的特定查询计划中的某个节点。当你调用 ExecProcNode 并传递一个计划节点作为参数时,它将执行该节点描述的操作,并返回结果元组。这是数据库查询执行中的关键部分,它使查询计划得以实际执行并生成结果。

总结

  “ExecutePlan” 函数负责执行查询计划中的各个节点,将它们的执行结果组合成最终的查询结果,并返回给调用者。这是数据库查询执行的核心部分,它确保了查询计划的实际执行和结果的生成。注意,具体实现和细节可能会因数据库管理系统而异。

  • 输入参数通常,“ExecutePlan” 函数将接受一个查询计划作为输入参数。这个查询计划通常是一个包含了多个执行计划节点(PlanState)的树状结构,每个节点描述了执行查询的不同操作。
  • 执行计划节点ExecutePlan” 函数将遍历查询计划中的每个执行计划节点,并逐一执行它们。这些节点可以包括扫描表、连接表、过滤数据、聚合操作等等,每个节点都有一个相应的执行方法。
  • 节点执行ExecutePlan” 函数将调用每个节点的执行方法(通常是 ExecProcNode 函数)来执行节点描述的操作。这些执行方法通常会访问数据库表、处理数据,或者进行其他计算操作,最终生成一个或多个结果元组。
  • 结果处理ExecutePlan” 函数通常会收集每个节点的执行结果,并根据查询的需求进行合并、过滤或其他操作。最终的结果可以是一个或多个元组,这些元组表示了查询的输出。
  • 返回结果ExecutePlan” 函数通常将最终的查询结果返回给调用者,以供后续处理或返回给客户端应用程序。

总之,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/624806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超详细!4小时开发一个SpringBoot+vue前后端分离博客项目!!

超详细!4小时开发一个SpringBootvue前后端分离博客项目!! 前后端分离项目 文章总体分为2大部分,Java后端接口和vue前端页面,比较长,因为不想分开发布,真正想你4小时学会,哈哈。 先…

【自学笔记】01Java基础-07面向对象基础-04接口与内部类详解

记录学习Java基础中有关接口类和内部类的知识。 1 接口 interface 关键字用于定义接口类,接口类是一系列方法的声明,一般只有方法的特征没有方法的实现,因此可以被不同的类接入实现,而这些实现可以具有不同的行为(功…

Graham扫描凸包算法

凸包(Convex Hull)是包含给定点集合的最小凸多边形。凸包算法有多种实现方法,其中包括基于递增极角排序、Graham扫描、Jarvis步进法等。下面,我将提供一个简单的凸包算法实现,基于Graham扫描算法。 Graham扫描算法是一…

多级缓存架构(一)项目初始化

文章目录 一、项目克隆二、数据库准备三、项目工程准备 一、项目克隆 克隆此项目到本地 https://github.com/Xiamu-ssr/MultiCache 来到start目录下,分别有以下文件夹 docker:docker相关文件item-service:springboot项目 二、数据库准备 …

Ncast盈可视高清智能录播系统busiFacade RCE漏洞(CVE-2024-0305)

产品介绍 Ncast盈可视高清智能录播系统是一套新进的音视频录制和播放系统,旨在提供高质量,高清定制的录播功能。 漏洞描述 广州盈可视电子科技有限公司的高清智能录播系统存在信息泄露漏洞(CVE-2024-0305),攻击者可通过该漏洞,…

Sectigo的DV通配符https

Sectigo是近些年发展比较快速的CA认证机构,为了提升审核效率,在全国成立了审核机构,亚太审核中心的成立加快了Sectigo旗下的https证书的审核速度。Sectigo的https证书可以为网站安全提供有力支持,从而保护网站信息安全。今天就随S…

3、深入解析Redis Cluster集群运维与核心原理

在今天的大规模分布式系统中,Redis Cluster已经成为了许多企业选择的分布式缓存方案之一。了解Redis Cluster的运维及核心原理对于确保系统的高可用性和性能至关重要。本文将深入探讨Redis Cluster集群的运维细节和核心原理,以帮助读者更好地理解和优化R…

【STM32】STM32学习笔记-MPU6050简介(32)

00. 目录 文章目录 00. 目录01. MPU6050简介02. MPU6050参数03. MPU6050硬件电路04. MPU6050框图05. MPU6050常用寄存器06. 附录 01. MPU6050简介 •MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合&#xff0…

网站监测工具的极与极,Site24x7 与百川云

今天我们聊聊我用 Site24x7 的感受。对于有网站监测有需求的站长们来说,Site24x7 确实是个很强大的应用。但是它与百川云网站监测完全不一样,百川云网站监测是适合用中小微企业的交互极简的saas 应用,Site24x7 完全是另一个极端,适…

datax关系数据库插件设计和实现解释

背景 DataX是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。解决异构数据源同步问题,DataX将复杂的网状的同步链路变成了星型数据链路&#xff0…

勒索家族瞄准制造业,亚信安全发布《勒索家族和勒索事件监控报告》

本周态势快速感知 本周(2024年第二期)全球共监测到勒索事件37起,事件数量持续下降,降至近半年最低值。 lockbit3.0仍然是影响最严重的勒索家族;akira和bianlian恶意家族也是两个活动频繁的恶意家族,需要注…

KubeSphere 在 vsleem 的落地实践

作者:方忠,苏州威视通智能科技有限公司技术经理,开源技术爱好者,长期活跃于 dromara 开源社区并参与贡献。 公司介绍 公司简介 苏州威视通智能科技有限公司,是一家全球领先的全景 AI 平台提供商,结合极致…

1.15作业

使用计数型信号量设计:生产者和消费者模型 总结今天学习的API函数,写出函数参数和返回值的意思,并且说明函数功能 创建队列 osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_si…

Java项目:121SSM记账管理系统

博主主页:Java旅途 简介:分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 记账管理系统基于SpringSpringMVCMybatis开发,系统主要功能如下: 收入项管理 支出项管理 收入方式管理 支出方式管理 添加收入…

《ORANGE’S:一个操作系统的实现》读书笔记(三十一)文件系统(六)

上一篇文章记录了对文件的读写操作,那么文件操作到目前为止,已经完成了创建和读写,还剩下的常用操作就是删除文件了。这篇文章就来记录删除文件的实现以及总结一下为文件系统添加系统调用的步骤。 删除文件 删除是添加的反过程,…

微服务自动化docker-compose

一、docker-compose介绍 Docker Compose是一个用来定义和运行多个复杂应用的Docker编排工具。例如,一个使用Docker容器的微服务项目,通常由多个容器应用组成。那么部署时如何快速启动各个微服务呢,一个个手动启动?假如有上百个微服…

计算机毕业设计 | SpringBoot+vue校园问卷调查系统(附源码)

1,绪论 研究目的 在进入21世纪以后,互联网得到了蓬勃的发展,电子问卷调查也开始逐渐流行起来。传统纸质问卷和电子问卷相比较后,传统问卷还存在很多弊端: 问卷分发起来比较困难,并且分发试卷耗费大量的金…

CSS 基本选择器 复合选择器

文章目录 基本选择器标记选择器类别选择器ID选择器测试基本选择器 复合选择器交集选择器并集选择器后代选择器全选选择器测试复合选择器 基本选择器 准备几个HTML标签用来测试 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"U…

智能小程序能做什么?

一. 自定义Tab页 涂鸦提供了丰富的场景化、个性化的 ToC 智能服务&#xff0c;不仅可以快速低成本的自由搭建出更多智能服务&#xff0c;还为你提供了基于小程序技术方案的可自主可控的自定义开发链路&#xff0c;为拓展更多品牌化、个性化、差异化智能服务提供生态基础。 我…

Javaweb之SpringBootWeb案例的详细解析

SpringBootWeb案例 前面我们已经讲解了Web前端开发的基础知识&#xff0c;也讲解了Web后端开发的基础(HTTP协议、请求响应)&#xff0c;并且也讲解了数据库MySQL&#xff0c;以及通过Mybatis框架如何来完成数据库的基本操作。 那接下来&#xff0c;我们就通过一个案例&#xf…