前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Postgresql源码(119)PL/pgSQL中ExprContext的生命周期

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

作者头像
mingjie
发布2023-12-30 08:09:30
1550
发布2023-12-30 08:09:30
举报
文章被收录于专栏:Postgresql源码分析

前言

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

代码语言:javascript
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 数据角度看PL中的ExprContext
  • 调用流程看PL中的ExprContext
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档