当前位置: 首页 > news >正文

Postgresql源码(119)PL/pgSQL中ExprContext的生命周期

前言

在PL/pgSQL语言中,执行任何SQL都需要通过SPI调用SQL层解析执行,例如在SQL层执行表达式的入口:

static bool
exec_eval_simple_expr(PLpgSQL_execstate *estate,PLpgSQL_expr *expr,Datum *result,bool *isNull,Oid *rettype,int32 *rettypmod)
{ExprContext *econtext = estate->eval_econtext;......*result = ExecEvalExpr(expr->expr_simple_state,econtext,isNull);......

表达式的运行时、内存都是在ExprContext中存放的,所以PL在调用任何函数前都会提前申请好ExprContext内存,执行表达式时可以直接使用。

使用后都会调用exec_eval_cleanup把eval_econtext的内存reset掉,避免影响后面执行的表达式。

在SQL层,ExprContext内存往往是挂在EState(SQL层的运行时)下的,PL也仿照SQL层做了一些事情,下面展开讲讲。

数据角度看PL中的ExprContext

  1. 例如在三层函数调用下,会产生三层PLpgSQL_execstate结构,代表PL的运行时。
  2. 无论几层函数,每层的PLpgSQL_execstate都会公用一个EState,EState会申请上下文es_query_cxt挂在事务上下文下,随顶层事务释放。所以在PL中执行COMMI后,所有子事务、顶层事务都会重建,EState上下文也会跟随释放,也需要重建。
  3. 每层函数的PLpgSQL_execstate都会自带ExprContext,这些ExprContext统一申请在ecxt_per_tuple_memory中,而ecxt_per_tuple_memory统一挂在同一个共享的es_query_cxt下。
  4. PL中事务提交分两种情况
    • 子事务提交:即exception子事务提交,这时顶层EState无需释放,只需要释放各层的ExprContext,这里通过simple_econtext_stack全局链表,按当前提交的子事务ID匹配,将对应的ExprContext释放掉。
    • 主事务提交:即顶层事务提交,这里会一次性的直接释放EState的内存es_query_cxt,跟随的EState和所有ExprContext都需要重建。
      在这里插入图片描述

调用流程看PL中的ExprContext

  1. exec_stmt_block中执行前,会把ExprContext用栈变量记录下来,执行完了再恢复出来。
  2. 带exception的执行前,都会先起子事务在新申请一个和新子事务绑定的ExprContext,用完即毁。
  3. 注意这里有两类ExprContext
    • 第一类是函数进入时就申请的,跟着plpgsql_estate_setup生成,这类ExprContext在整个调用流程结束时,会被plpgsql_exec_function主动释放,所以这类ExprContext不能再内部提前清理,否则外面清理时就会有问题。
    • 第二类是有exception时在起完子事务,执行具体的stmt前申请的,和新子事务绑定,这类PL是不会主动释放的,都是跟随当前子事务销毁的。无论子事务提交还是回滚,这个ExprContext都会被释放。

在这里插入图片描述

PL内执行commit时
在这里插入图片描述
多层函数时PL内执行commit
在这里插入图片描述

相关文章:

  • 3D视觉-相机选用的原则
  • STM32 基础知识(探索者开发板)--135讲 ADC转换
  • 金和OA C6 UploadFileEditorSave.aspx 文件上传漏洞复现
  • Elasticsearch 优化常用思路
  • 防火墙未开端口导致zookeeper集群异常,kafka起不来
  • Unity检测地面坡度丨人物上坡检测
  • 【elfboard linux开发板】7.i2C工具应用与aht20温湿度寄存器读取
  • Qt编写的exe程序上添加程序信息
  • 介绍Docker的基本概念和优势,以及在应用程序开发中的实际应用
  • 从Windows 1.0到Windows 10的旅程:探索Windows系统的起源和第一个版本特点
  • 二叉树的后序遍历,力扣
  • Spring Boot快速搭建一个简易商城项目【完成登录功能且优化】
  • Axure医疗-住院板块,住院患者原型预览,新增医护人员原型预览,新增病房原型预览,选择床位原型预览,主治医生原型预览,主治医生医嘱原型预览
  • Mybaits-plus快速入门
  • 大学生必备的15个网站,大学生考试报名,大学生自学网站!
  • 「面试题」如何实现一个圣杯布局?
  • crontab执行失败的多种原因
  • Javascript编码规范
  • Java程序员幽默爆笑锦集
  • java正则表式的使用
  • Java知识点总结(JavaIO-打印流)
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • ViewService——一种保证客户端与服务端同步的方法
  • 第十八天-企业应用架构模式-基本模式
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 我的面试准备过程--容器(更新中)
  • 小试R空间处理新库sf
  • 在Mac OS X上安装 Ruby运行环境
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • #if 1...#endif
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (八)Flask之app.route装饰器函数的参数
  • (二)斐波那契Fabonacci函数
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (转载)Linux 多线程条件变量同步
  • (轉貼) UML中文FAQ (OO) (UML)
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .Net IOC框架入门之一 Unity
  • .net程序集学习心得
  • @JoinTable会自动删除关联表的数据
  • @JsonSerialize注解的使用
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [AUTOSAR][诊断管理][ECU][$37] 请求退出传输。终止数据传输的(上传/下载)
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [BT]BUUCTF刷题第4天(3.22)
  • [BZOJ4016][FJOI2014]最短路径树问题