Postgresql源码(100)Portal与事务的关系(顶层事务与子事务)
1 总结
-
portal与事务有强绑定的关系,由portal->createSubid变量记录关联关系。如果为1表示顶层事务,关联的是子事务。
-
不论是顶层事务还是子事务,提交、回滚时只会处理自己创建出来的portal。
- 顶层事务会清理非活跃状态的Portal,如果Portal是活跃的会保留内存。
- 子事务直接释放portal,无论是否活跃。
-
PLpgSQL中的提交回滚,有较大限制:
- PLpgSQL中的提交或回滚,如果call proc在事务块中,直接失败。
- PLpgSQL中的提交或回滚,如果pl带exception,直接失败。
- 原因是,pl中的提交或回滚不能再子事务、或事务块内,要实现的话比较复杂,需要对齐SPI与子事务、portal与子事务、exprcontext与子事务等等。
-
子事务ID只增不减,可能有空隙存在,参考PushTransaction的currentSubTransactionId。
2 提交
2.1 顶层事务提交:PreCommit_Portals与子事务提交AtSubCommit_Portals
实例
CREATE OR REPLACE PROCEDURE tproc1()
AS $$
DECLAREcurs1 refcursor; curs2 CURSOR FOR SELECT c1 FROM tf1;curs3 CURSOR (key integer) FOR SELECT * FROM tf1 WHERE c1 > key;x int;y tf1%ROWTYPE;
BEGINopen curs1 FOR SELECT * FROM tf1 WHERE c1 > 3;fetch curs1 into y; RAISE NOTICE 'curs1 : %', y.c3;fetch curs1 into y; RAISE NOTICE 'curs1 : %', y.c3;open curs2;fetch curs2 into x; RAISE NOTICE 'curs2 : %', x;fetch curs2 into x; RAISE NOTICE 'curs2 : %', x;OPEN curs3(4); -- OPEN curs3(key := 4);fetch curs3 into y; RAISE NOTICE 'curs3 : %', y.c4;fetch curs3 into y; RAISE NOTICE 'curs3 : %', y.c4;
EXCEPTION WHEN others THENRAISE NOTICE 'in caller exception';
END;
$$ LANGUAGE plpgsql;begin;
savepoint sp1;
savepoint sp2;
call tproc1();
commit;
(1)第一次子事务提交:EXCEPTION子事务提交AtSubCommit_Portals(subid=4)
发生在call tproc1();执行完毕。
exec_stmt_blockReleaseCurrentSubTransactionCommitSubTransactionAtSubCommit_Portals
当前事务堆栈:
CurrentTransactionState->subTransactionId
[1, 2, 3, 4]| | | |
top savepoint savepoint exception
由于call进入SPI,当前SPI堆栈只有一层,对应到3号子事务上,因为是在3号子事务的背景下执行的CALL。
_SPI_stack[0] = {connectSubid = 3}
AtSubCommit_Portals(mySubid=4) 开始处理portal:
portal1 = { // 游标 mySubid = 4 ,当前游标的portal被继承给parent portalname = "<unnamed portal 17>", createSubid = 4, // AtSubCommit_Portals 4-->3activeSubid = 4,createLevel = 4, sourceText = "SELECT c1 FROM tf1",commandTag = CMDTAG_SELECT,strategy = PORTAL_ONE_SELECT}
… 三个游标的portal都是类似上面处理的。特殊的是顶层portal。不属于当前要释放的子事务4,不处理。
portal1 = { // 顶层 mySubid = 3 ,当前不处理name = "", createSubid = 3, activeSubid = 3, createLevel = 3, sourceText = "call tproc1();",commandTag = CMDTAG_CALL,strategy = PORTAL_MULTI_QUERY}
(2)第二次子事务提交:savepoint子事务提交AtSubCommit_Portals(subid=3)
发生在commit。
exec_simple_queryfinish_xact_commandCommitTransactionCommandCommitSubTransactionAtSubCommit_Portals
当前事务堆栈:
CurrentTransactionState->subTransactionId
[1, 2, 3]| | |
top savepoint savepoint
AtSubCommit_Portals(mySubid=3)开始处理portal:
portal1 = { // 游标 mySubid = 4 ,当前游标的portal被继承给parent portalname = "<unnamed portal 17>", createSubid = 2, // AtSubCommit_Portals 3-->2activeSubid = 2, // AtSubCommit_Portals 3createLevel = 2, // AtSubCommit_Portals 3-->2sourceText = "SELECT c1 FROM tf1",commandTag = CMDTAG_SELECT,strategy = PORTAL_ONE_SELECT}
当前堆栈Portal已经被drop了。现在PortalHashTable里面只有三个游标的Portal。
(3)第三次子事务提交:savepoint子事务提交(subid=2)
同上。
(4)顶层事务提交(subid=1)PreCommit_Portals
发生在commit。
exec_simple_queryfinish_xact_commandCommitTransactionCommandCommitTransactionPreCommit_Portals
提交时发现3个portal,只剩游标的3个portal了。
调用PortalDrop全部释放掉。
PreCommit_Portals函数需要关注的就是,普通portal都会被drop掉。特殊保留的是hold cursor即循环语句使用的内部自建游标,还有一种就是vacuum等多事务语句。
3 回滚
3.1 顶层事务清理:AtAbort_Portals
调用位置
AbortTransaction → AtAbort_Portals
调用一次即可,用户清理顶层事务。
清理逻辑
- 遍历PortalHashTable,拿到所有CreatePortal创建出来的Portal(两种:执行器的portal和游标的portal)
- 标记portal状态failed,标记failed的内存会被释放掉。
- 情况一:elog FATAL 主动标记failed
- 情况二:状态是PORTAL_READY的portal
- 跳过一些portal,不处理。
- 情况一:createSubid=0 前一个事务的portal,不属于自己(!=1)。
- 情况二:portal->autoHeld == true 专门用于循环的游标(不是用户创建的,PL自用的)。
3.2 子事务清理:AtSubAbort_Portals
调用位置
AbortSubTransaction → AtSubAbort_Portals
有两种调用场景:
- 事务块内一次性rollback,递归多次AtSubAbort_Portals,提交所有子事务。
- 回滚到某一个检查点,递归指定次数AtSubAbort_Portals,只提交指定的几个子事务。
清理逻辑
- 遍历PortalHashTable,拿到所有CreatePortal创建出来的Portal(两种:执行器的portal和游标的portal)
- 判断创建归属:
- 如果当前清理的子事务 与 portal的createSubid匹配,直接清理PORTAL_READY和PORTAL_ACTIVE状态的,包括删除内存。
- 如果当前清理的子事务 与 portal的createSubid不匹配:
- 判断使用归属,如果当前清理的子事务 与 portal的activeSubid匹配,说明不是当前子事务创建的,但是被当前子事务使用了,指标记failed但不做清理,不删除内存。
4 PushTransaction与PopTransaction函数
- 启动子事务时需要将当前事务入栈,CurrentTransactionState换成子事务的。
- 子事务和父事务由parent连接。
- 修改这部分代码需要注意一次弹出多个事务时,currentSubTransactionId有没有正确维护。
static void
PushTransaction(void)
{TransactionState p = CurrentTransactionState;TransactionState s;s = (TransactionState)MemoryContextAllocZero(TopTransactionContext,sizeof(TransactionStateData));
注意currentSubTransactionId直增不减。pop时也不减少。
currentSubTransactionId += 1;if (currentSubTransactionId == InvalidSubTransactionId){currentSubTransactionId -= 1;pfree(s);ereport(ERROR,(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));}/** We can now stack a minimally valid subtransaction without fear of* failure.*/s->fullTransactionId = InvalidFullTransactionId; /* until assigned */s->subTransactionId = currentSubTransactionId;s->parent = p;s->nestingLevel = p->nestingLevel + 1;s->gucNestLevel = NewGUCNestLevel();s->savepointLevel = p->savepointLevel;s->state = TRANS_DEFAULT;s->blockState = TBLOCK_SUBBEGIN;GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);s->prevXactReadOnly = XactReadOnly;s->parallelModeLevel = 0;s->topXidLogged = false;CurrentTransactionState = s;}
相关文章:
Postgresql源码(100)Portal与事务的关系(顶层事务与子事务)
1 总结 portal与事务有强绑定的关系,由portal->createSubid变量记录关联关系。如果为1表示顶层事务,关联的是子事务。 不论是顶层事务还是子事务,提交、回滚时只会处理自己创建出来的portal。 顶层事务会清理非活跃状态的Portalÿ…...
Java、JSP企业快信系统的设计与实现
技术:Java、JSP等摘要:计算机网络的出现到现在已经经历了翻天覆地的重大改变。因特网也从最早的供科学家交流心得的简单的文本浏览器发展成为了商务和信息的中心。到了今天,互联网已经成为了大量应用的首选平台,人们已经渐渐习惯了…...
1.2(完结)C语言进阶易忘点速记
1.大端存储:高权位数字放在低地址处,低权位数字放在高地指处。(以字节为单位) 2.小端存储:低权位数字放在低地址处,高权位数字放在高地址处。(以字节为单位) 3.变量(char类型)进行运算的时候一定要注意整形提升与截断࿰…...
雅思经验(十一)
写作:WRITINGTASK 2Governments should spend money on railways rather than roads.To what extent do you agree or disagree with this statement?Give reasons for your answer and include any relevant examples from your own knowledge or experience.思路…...
C++中的智能指针
1.RAII 与引用计数了解 Objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象,进行引用计数,每当增加一次对同一个对象的引用,那么引用对象的引用计数就会增加一次…...
LSTM已死,Transformer当立(LSTM is dead. Long Live Transformers! ):下
2017 年,Google 在论文 Attention is All you need 中提出了 Transformer 模型,其使用 Self-Attention 结构取代了在 NLP 任务中常用的 RNN 网络结构。而且实验也证明Transformer 在效果上已经完败传统的 RNN 网络。Transformer 的整体模型架构如下图所示。尽管它看起来还是很…...
OJ万题详解––[NOIP2004 提高组] 合并果子(C++详解)
目录 题目 分析 参考代码 题目 题目描述 一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的…...
MySQL-字符集和比较规则
在计算机中只能存储二进制数据,那该怎么存储字符串呢?当然是建立字符与二进制数据的映射关系 了,建立这个关系最起码要搞清楚两件事: 界定清楚字符范围:需要把哪些字符映射成二进制数据?编码与解码&#x…...
微搭低代码从入门到精通12-网格布局
开发小程序首要的就是考虑布局的问题,我们在以前的版本只能选择普通容器结合图片和文本组件来构建页面。 使用通用组件布局也可以,但有个问题是你要先学习CSS,要懂布局的概念,比如需要知道啥是flex布局,然后还得熟悉每…...
【c语言】二叉树
主页:114514的代码大冒险 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 引入 我们之前已经学过线性数据结构,今天我们将介绍非线性数据结构----树 树是一种非线性的…...
六、Java框架之SpringBoot
黑马课程 文章目录1. SpringBoot入门1.1 SpringBoot入门案例步骤1:创建SpringBoot项目高版本springboot常见错误步骤2:创建BookController步骤3:启动服务器并运行程序pom.xml示例1.2 官网创建SpringBoot1.3 SpringBoot工程快速启动问题导入打…...
「Python|环境安装|Windows」如何在Windows上安装Python环境?
本文主要介绍如何在Windows上安装Python,帮助初学者或者非程序员伙伴快速搭建可以运行python代码的环境。 文章目录安装python做一点小配置验证python如何安装指定版本的python编程语言的环境搭建一直是学习编程的第一道门槛。 对于如何在Linux系统上安装指定版本的…...
人工智能轨道交通行业周刊-第33期(2023.2.6-2.12)
本期关键词:高铁激光清洗、高铁确认列车、无线通信系统、推理服务优化、量子信息技术 1 整理涉及公众号名单 1.1 行业类 RT轨道交通中关村轨道交通产业服务平台人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟V…...
五分钟看懂Java字节码:极简手册
字节码新手很容易被厚厚的 JVM 书籍劝退,即使我看过相关书籍,工作真正用到时也全忘了,还得现学。 等我有了一定的字节码阅读经验,才发现字节码其实非常简单,只需要三步就能快速学会: 先了解 JVM 的基本结…...
C++ 类与对象(下)
✅<1>主页:我的代码爱吃辣 📃<2>知识讲解:C 🔥<3>创作者:我的代码爱吃辣 ☂️<4>开发环境:Visual Studio 2022 💬<5>前言:C类与对象的收尾工作&#…...
Java基础——I/O
一、异常 异常是程序中可能出现的问题,它的父类是Exception。异常分为两类,编译时异常、运行时异常。 编译时异常:没有继承RuntimeException的异常,直接继承于Exception。编译阶段就会错误提示。运行时异常:RuntimeE…...
关于@hide的理解
在上一篇文章《学习HandlerThread》我们提到虽然HandlerThread类里有getThreadHandler()方法得到Handler,但是我们不可能调用到它。因为这个方法用hide注释了 /*** return a shared {link Handler} associated with this thread* hide*/NonNullpublic Handler getT…...
使用python加密主机文件几种方法实现
本文主要介绍了使用python加密主机文件几种方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧数据加密是一种保护数据安全的技术,通过对数据进行编…...
西湖论剑 2023 比赛复现
WEB real_ez_node 在 route/index.js 中: router.post(/copy,(req,res)>{res.setHeader(Content-type,text/html;charsetutf-8)var ip req.connection.remoteAddress;console.log(ip);var obj {msg: ,}if (!ip.includes(127.0.0.1)) {obj.msg"only for…...
微信小程序更换管理员/重置管理员
方式1: 首先进入微信公众平台官网进入并登录后在管理中找到成员管理选项找到管理员点击后方的修改选项需要使用原管理员的微信进行扫码验证扫码后在手机上确认绑定新管理员,注意:如果是个人账号不可以更改成其他人。 方式2:原管…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
