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

news/2024/2/23 16:23:43/文章来源:https://blog.csdn.net/qq_43899283/article/details/135616807

执行器(ExecEndPlan)

  • 概述
  • ExecEndPlan 函数
    • ExecEndNode 函数
  • 总结

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

概述

  在这三篇文章中,首先是【OpenGauss源码学习 —— 执行器(execMain)】,它详细探讨了 OpenGauss 数据库管理系统中执行器模块的主要功能和实现机制。这部分内容涉及到如何在 OpenGauss 环境下处理和执行 SQL 语句,包括查询计划生成和优化,以及如何有效地管理数据流和处理结果
  接着,【PostgreSQL内核学习(二十一)—— 执行器(InitPlan)】专注于 PostgreSQL 数据库的执行器模块,特别是初始化计划(InitPlan)的部分。这篇文章讨论了在执行查询之前,如何准备和设置执行环境,包括加载必要的数据结构、分配资源等。这是理解 PostgreSQL 查询处理的关键部分,涉及到数据库内核的深层次工作机制。
  最后,【PostgreSQL内核学习(二十二)—— 执行器(ExecutePlan)】则是关于 PostgreSQL 执行器中执行计划ExecutePlan)的详细分析。这部分内容深入探讨了如何将初始化阶段准备好的计划转化为实际的操作,执行具体的查询。它包括了查询的执行流程,以及如何处理和优化各种数据库操作
  简单总结,这三篇文章都集中在数据库管理系统中的执行器模块,讲述了从初始化计划到执行计划的整个过程。通过深入分析 OpenGaussPostgreSQL 中的实现细节,这些文章为理解优化数据库查询处理提供了宝贵的视角。对数据库开发者和研究者来说,这些内容无疑是非常有价值的资源。
  本文最后将深入了解 ExecEndPlan原理实现细节,从而更好地理解数据库查询的执行机制。具体学习的模块如下图红色框体所示:
在这里插入图片描述

ExecEndPlan 函数

  ExecEndPlan 函数的功能是结束查询计划的执行,主要负责清理和释放在查询执行过程中创建和占用的资源。这包括关闭特定节点类型的查询处理处理子计划销毁执行器的元组表(同时释放缓冲区引脚和元组描述符的引用计数),关闭结果关系相关的索引,以及处理触发器状态和行标记。代码的主要目的是确保所有打开的文件和资源得到适当的关闭和释放,以维护系统的稳定性和效率。函数源码如下所示:(路径:src\backend\executor\execMain.c

/* ----------------------------------------------------------------*      ExecEndPlan**      清理查询计划 —— 关闭文件并释放存储** 注意:现在不太需要担心这段代码中的存储释放;* FreeExecutorState应该保证释放所有需要释放的内存。我们关心的是* 关闭关联关系和丢弃缓冲区引脚。因此,元组表必须被清空或丢弃以确保引脚被释放。* ----------------------------------------------------------------*/
static void
ExecEndPlan(PlanState *planstate, EState *estate)
{ResultRelInfo *resultRelInfo;int i;ListCell *l;/** 关闭节点类型特定的查询处理*/ExecEndNode(planstate);/** 同样处理子计划*/foreach(l, estate->es_subplanstates){PlanState *subplanstate = (PlanState *) lfirst(l);ExecEndNode(subplanstate);}/** 销毁执行器的元组表。实际上我们只关心释放缓冲区引脚和元组描述符的引用计数;* 没有必要释放TupleTableSlots,因为包含它们的内存上下文马上就会消失。*/ExecResetTupleTable(estate->es_tupleTable, false);/** 如果有的话,关闭结果关系,但在事务提交前保持锁定。*/resultRelInfo = estate->es_result_relations;for (i = estate->es_num_result_relations; i > 0; i--){/* 先关闭索引,然后关闭关系本身 */ExecCloseIndices(resultRelInfo);heap_close(resultRelInfo->ri_RelationDesc, NoLock);resultRelInfo++;}/* 关闭根目标关系。 */resultRelInfo = estate->es_root_result_relations;for (i = estate->es_num_root_result_relations; i > 0; i--){heap_close(resultRelInfo->ri_RelationDesc, NoLock);resultRelInfo++;}/* 同样关闭任何触发器目标关系 */ExecCleanUpTriggerState(estate);/** 关闭任何为[KEY] UPDATE/SHARE所选的关系,同样保持锁定。*/foreach(l, estate->es_rowMarks){ExecRowMark *erm = (ExecRowMark *) lfirst(l);if (erm->relation)heap_close(erm->relation, NoLock);}
}

ExecEndNode 函数

  ExecEndNode 函数的主要功能是递归地遍历查询计划中的每个节点,并对每个节点执行特定的结束操作。这包括释放节点相关的资源关闭打开的文件和连接,以及清理节点内部状态。这个过程对于确保在查询执行完毕后,所有的资源都得到妥善处理非常重要,以避免内存泄漏和其他潜在的问题。函数通过对不同类型的节点执行不同的结束操作(如 ExecEndResultExecEndSeqScan 等),实现了对整个查询计划的全面清理。函数源码如下所示:(路径:src\backend\executor\execProcnode.c

/* ----------------------------------------------------------------*      ExecEndNode**      递归地清理以'node'为根的查询计划中的所有节点。**      此操作完成后,查询计划将无法继续处理。这应该在查询计划*      完全执行完毕后才调用。* ----------------------------------------------------------------*/
void
ExecEndNode(PlanState *node)
{/** 当到达树叶节点时,无需进行任何操作。*/if (node == NULL)return;/** 确保有足够的栈空间可用。需要在这里检查,除了在ExecProcNode()中检查,* 因为不能保证所有节点都能到达ExecProcNode()。*/check_stack_depth();if (node->chgParam != NULL){bms_free(node->chgParam);node->chgParam = NULL;}switch (nodeTag(node)){/** 控制节点*/case T_ResultState:ExecEndResult((ResultState *) node);break;// ... 其他控制节点的处理 .../** 扫描节点*/case T_SeqScanState:ExecEndSeqScan((SeqScanState *) node);break;// ... 其他扫描节点的处理 .../** 连接节点*/case T_NestLoopState:ExecEndNestLoop((NestLoopState *) node);break;// ... 其他连接节点的处理 .../** 物化节点*/case T_MaterialState:ExecEndMaterial((MaterialState *) node);break;// ... 其他物化节点的处理 ...default:elog(ERROR, "无法识别的节点类型: %d", (int) nodeTag(node));break;}
}

总结

  以上内容描述了 PostgreSQL 数据库中的 ExecEndNode 函数,这是一个用于递归清理查询计划中所有节点的重要功能。该函数在查询计划执行完毕后被调用,负责释放各个节点占用的资源关闭相关文件和连接、以及清理内部状态。它通过检查每个节点的类型,并对不同类型的节点调用相应的结束处理函数(如 ExecEndResultExecEndSeqScan 等),来确保资源得到妥善管理。这个过程对于维护数据库系统的稳定性和效率至关重要,能有效防止内存泄露和其他潜在问题。

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

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

相关文章

压力测试+接口测试(工具jmeter)

jmeter是apache公司基于java开发的一款开源压力测试工具,体积小,功能全,使用方便,是一个比较轻量级的测试工具,使用起来非常简单。因 为jmeter是java开发的,所以运行的时候必须先要安装jdk才可以。jmeter是…

opencv-4.8.0编译及使用

1 编译 opencv的编译总体来说比较简单,但必须记住一点:opencv的版本必须和opencv_contrib的版本保持一致。例如opencv使用4.8.0,opencv_contrib也必须使用4.8.0。 进入opencv和opencv_contrib的github页面后,默认看到的是git分支&…

DC电源模块与AC电源模块的对比分析

DC电源模块与AC电源模块的对比分析 BOSHIDA DC电源模块和AC电源模块是两种常见的电源模块,它们在供电方式、稳定性、适用范围等方面有所不同,下面是它们的对比分析: 1. 供电方式: DC电源模块通过直流电源供电,通常使用…

shiro实战

接下来我将用编码的方式,来演示如何使用shirojwt实现认证并下发token,但是没有整合到springboot中。只是shiro的API的调用 1. shirojwt 实现登录认证、获取资源的流程图 2.编码实现 (1)工程结构 (2)核心代…

msvcr110.dll缺失怎么解决,修复msvcr110.dll缺失的方法分享

首先,我们来了解一下msvcr110.dll是什么文件。msvcr110.dll是Microsoft Visual C 2012 Redistributable的一个组件,它包含了许多运行库函数,这些函数在编译和运行使用Visual C编写的程序时是必不可少的。简单来说,msvcr110.dll就是…

Unity解决Udp客户端无法接收数据的问题

Unity解决Udp客户端无法接收数据的问题 在我之前做过的项目中,其中不少涉及Udp客户端的项目。在这些项目中,一般只需要实现客户端向服务器端发送数据的功能就可以了,一般都不用接收服务器端发送的数据,但是也有同学使用了我分享的…

[C#]winform部署官方yolov8-obb旋转框检测的onnx模型

【官方框架地址】 https://github.com/ultralytics/ultralytics 【算法介绍】 Yolov8-obb(You Only Look Once version 8 with Oriented Bounding Boxes)是一种先进的对象检测算法,它在传统的Yolov3和Yolov4基础上进行了优化,加…

Next.js 开发指​南(GitHub 115k star​)

Next.js 是一个构建于 Node.js 之上的开源 Web 开发框架,它扩展了最新的 React 特性,集成了基于 Rust 的 JavaScript 工具,可以帮助你快速创建全栈 Web 应用 (full-stack Web applications) 。 对于有一定 React 基础…

软件测试|使用selenium进行多窗口操作

简介 在我们进行自动化测试的工作中,经常会点击某个元素或者链接就会自动打开一个新页面,需要我们转到新打开的页面去进行操作,这个时候我们就需要能够自动切换到新页面进行后续的操作,selenium同样支持这个功能,本文…

FineBI报表页面大屏小屏自适应显示问题

大屏正常显示 显示正常 小屏BI自适应显示 存在遮挡字体情况 小屏浏览器缩放显示 等比缩放后显示正常

【CV】使用 matplotlib 画统计图,并用 OpenCV 显示静图和动图

1. 效果 静图 动图 2.思路 准备数据使用 pyplot 画统计图图片写入流,流转图(numpy)matplotlib 颜色 RGB 转 OpenCV 颜色 BRG 4. 静图 代码过程有注释,很简单的实现。注意 matplotlib RGB 转 OpenCV BGR image image[:, :,…

【51单片机系列】proteus仿真单片机的串口通信

本文参考:https://zhuanlan.zhihu.com/p/425809292。 在proteus之外使用串口软件和单片机通信。通过在proteus设计一个单片机接收PC发送的数据,并将接收的数据发送出去,利用软件【Configure Virtual Serial Port Driver】创建一对虚拟串口&am…

网络安全技术新手入门:利用永恒之蓝获取靶机控制权限

目录 前言 一、搜索永恒之蓝可用模块 二、使用攻击模块 三、配置攻击模块 四、攻击 五、总结 前言 相关法律声明:《中华人民共和国网络安全法》第二十七条 任何个人和组织不得从事非法侵入他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的活动&…

php 的数学常用函数

目录 1.常用列表 2.代码示例 1.常用列表 函数名描述输入输出abs()求绝对值数字绝对值数字ceil()进一法取整浮点数进一取整floor()舍去法求整浮点数直接舍去小数部分fmod()浮点数取余 两个浮点 数,x>y 浮点余数 pow()返回数的n次方基础数n次方乘方值round()浮点数四舍五入…

数据结构期末复习(4)串 树和二叉树

串 在数据结构中,串是由零个或多个字符组成的有限序列。它是一种线性数据结构,常用于表示和处理文本、字符串等信息。 串的特点包括: 顺序性:串中的字符按照一定的先后顺序排列,每个字符都有一个唯一的位置。有限性&…

关于并发十道常见面试题

面试题一:线程中的start和run方法有什么区别 Java中线程是通过Thread类来实现的,每个线程都是通过特定的Thread对象所对应的run方法来完成 start()方法来启动线程,真正的实现多线程,这时无需等待run&…

华为交换机配置NQA TCP检测IP网络响应时间

微思 | 华为HCIA试听课程:网络工程师的基本功:网络地址转换NAT 微思 | 华为HCIP试听课程:华为HCIP必考题:DHCP协议原理与配置 组网需求 如图1所示,总部和子公司之间需要跨越外部网络进行通信,DeviceA和De…

【学习iOS高质量开发】——熟悉Objective-C

文章目录 一、Objective-C的起源1.OC和其它面向对象语言2.OC和C语言3.要点 二、在类的头文件中尽量少引用其他头文件1.OC的文件2.向前声明的好处3.如何正确引入头文件4.要点 三、多用字面量语法,少用与之等价的方法1.何为字面量语法2.字面数值3.字面量数组4.字面量字…

Apache DolphinScheduler 3.1.8 保姆级教程【安装、介绍、项目运用、邮箱预警设置】轻松拿捏!

概述 Apache DolphinScheduler 是一个分布式易扩展的可视化 DAG 工作流任务调度开源系统。适用于企业级场景,提供了一个可视化操作任务、工作流和全生命周期数据处理过程的解决方案。 Apache DolphinScheduler 旨在解决复杂的大数据任务依赖关系,并为应…

浏览器网页内嵌Qt-C++音视频播放器的实现,支持软硬解码,支持音频,支持录像截图,支持多路播放等,提供源码工程下载

一.前言 在浏览器中实现播放RTSP实时视频流,⼤体上有如下⼏个⽅案: ⽅案一:浏览器插件⽅案 ActiveX、NPAPI、PPAPI ActiveX插件适用于IE浏览器,NPAPI与PPAPI插件适用于谷歌浏览器,不过这些插件都已经不被浏览器所支持…