PostgreSQL源码学习–调度器#14

PostgreSQL源码学习–调度器#14本节介绍PortalRun函数。 PortalRun函数 //src/include/tcop/pquery.h extern bool PortalRun(Portal portal, long …

PostgreSQL源码学习--调度器#14

本节介绍PortalRun函数。

PortalRun函数

//src/include/tcop/pquery.h

extern bool PortalRun(Portal portal, long count, bool isTopLevel,
				  bool run_once, DestReceiver *dest, DestReceiver *altdest,
				  char *completionTag);

代码100分

代码100分//src/backend/tcop/pquery.c

AssertArg(PortalIsValid(portal));

/* 动态追踪的探针 */
TRACE_POSTGRESQL_QUERY_EXECUTE_START();

/* 初始化completionTag */
if (completionTag)
	completionTag[0] = "";

/* 需要记录且portal策略不是multi_query时,在这里重置portal计时。
 * PORTAL_MULTI_QUERY 会为每个query分别计时(上节有讲) */
if (log_executor_stats && portal->strategy != PORTAL_MULTI_QUERY)
{
	elog(DEBUG3, "PortalRun");
	ResetUsage();
}

/* 检查portal是否被错误使用,并标记portal为active状态 */
MarkPortalActive(portal);

/* 设置run_once标志 */
Assert(!portal->run_once || run_once);
portal->run_once = run_once;

/* 设置全局portal上下文指针 */
saveTopTransactionResourceOwner = TopTransactionResourceOwner;
saveTopTransactionContext = TopTransactionContext;
saveActivePortal = ActivePortal;
saveResourceOwner = CurrentResourceOwner;
savePortalContext = PortalContext;
saveMemoryContext = CurrentMemoryContext;
PG_TRY();
{
	ActivePortal = portal;
	if (portal->resowner)
		CurrentResourceOwner = portal->resowner;
	PortalContext = portal->portalContext;
	
	/* 切换到portal的内存上下文 */
	MemoryContextSwitchTo(PortalContext);
	
	switch (portal->strategy)
	{
		case PORTAL_ONE_SELECT:
		case PORTAL_ONE_RETURNING:
		case PORTAL_ONE_MOD_WITH:
		case PORTAL_UTIL_SELECT:
			
			/* 将结果存储在portal的tuplestore中 */
			if (portal->strategy != PORTAL_ONE_SELECT && !portal->holdStore)
				FillPortalStore(portal, isTopLevel);
			
			/* 获取所需的结果 */
			nprocessed = PortalRunSelect(portal, true, count, dest);
			
			/* 处理completionTag */
			if (completionTag && portal->commandTag)
			{
				if (strcmp(portal->commandTag, "SELECT") == 0)
					snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
							 "SELECT " UINT64_FORMAT, nprocessed);
				else
					strcpy(completionTag, portal->commandTag);
			}
			
			/* 标记portal为no active状态 */
			portal->status = PORTAL_READY;
			
			/* 当且仅当atEnd为true时表示处理完成了 */
			result = portal->atEnd;
			break;
			
		/* 需要有多个query分开处理 */
		case PORTAL_MULTI_QUERY:
			PortalRunMulti(portal, isTopLevel, false,
						   dest, altdest, completionTag);
			
			/* 防止portal的命令被重新执行 */
			MarkPortalDone(portal);
			
			/* 这里总是true  */
			result = true;
			break;
			
		default:
			elog(ERROR, "unrecognized portal strategy: %d",
				 (int) portal->strategy);
			result = false; /* keep compiler quiet */
			break;
	}
}
PG_CATCH();
{
	/* 出现未捕获的异常,标记portal为failed */
	MarkPortalFailed(portal);
	
	/* 恢复全局变量并传递错误 */
	if (saveMemoryContext == saveTopTransactionContext)
		MemoryContextSwitchTo(TopTransactionContext);
	else
		MemoryContextSwitchTo(saveMemoryContext);
	ActivePortal = saveActivePortal;
	if (saveResourceOwner == saveTopTransactionResourceOwner)
		CurrentResourceOwner = TopTransactionResourceOwner;
	else
		CurrentResourceOwner = saveResourceOwner;
	PortalContext = savePortalContext;

	PG_RE_THROW();
}
PG_END_TRY();

/*  恢复全局变量 */
if (saveMemoryContext == saveTopTransactionContext)
	MemoryContextSwitchTo(TopTransactionContext);
else
	MemoryContextSwitchTo(saveMemoryContext);
ActivePortal = saveActivePortal;
if (saveResourceOwner == saveTopTransactionResourceOwner)
	CurrentResourceOwner = TopTransactionResourceOwner;
else
	CurrentResourceOwner = saveResourceOwner;
PortalContext = savePortalContext;

/* 需要记录且portal策略不是multi_query时,在这里输出portal计时 */
if (log_executor_stats && portal->strategy != PORTAL_MULTI_QUERY)
	ShowUsage("EXECUTOR STATISTICS");

/* 动态追踪的探针 */
TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();

return result;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7865.html

(0)
上一篇 2023-03-12
下一篇 2023-03-12

相关推荐

  • Python转换成小写字符串

    Python转换成小写字符串在Python中,字符串是一种非常常见的数据类型,我们经常需要对字符串进行各种操作,如转换大小写、截取子串、替换字符等等。在本文中,我们将主要探讨如何将一个Python字符串转换成小写字符串。

    2024-01-25
    53
  • 多属性、多分类MySQL模式设计[通俗易懂]

    多属性、多分类MySQL模式设计[通俗易懂]一、导读 这是来自B乎的一个问答。 当数据同时具备多个属性/分类时,改如何设计表结构和查询? 二、需求描述 我偶尔也会逛逛B乎,看到一些感兴趣的话题也会回复下。 有一次,看到这样的一个话题: 链接:…

    2022-12-25
    95
  • Web安全之SQL Inject[亲测有效]

    Web安全之SQL Inject[亲测有效]SQL Inject(SQL注入)概述 在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。 数据库注入漏洞,主要是开发人员在构建代…

    2023-04-04
    127
  • 1、基本概念[通俗易懂]

    1、基本概念[通俗易懂]1、数据库概念 数据库就是用来存储和管理数据的仓库。我们所说的数据库泛指“关系型数据库管理系统”,即“数据库服务器”。MySQL就是典型的关系型数据库。 数据库存储数据的优点: 可存储大量数据; 方…

    2023-04-12
    111
  • ORA-08177_ora-28547:connection

    ORA-08177_ora-28547:connection问题描述:还是rman的问题,一个很沙雕的问题,改了半天,准备是要做数据库的全备,和归档的备份 1.连接rman进行备份,这里要保持数据库为mount状态,因为要对数据库全备 [oracle@orcl

    2022-12-28
    107
  • Mysql主从同步的实现原理与配置实战

    Mysql主从同步的实现原理与配置实战1、什么是mysql主从同步? 当master(主)库的数据发生变化的时候,变化会实时的同步到slave(从)库。 2、主从同步有什么好处? 水平扩展数据库的负载能力。 容错,高可用。Failover

    2022-12-16
    99
  • Python中语法错误:关键字无法作为表达式的解释

    Python中语法错误:关键字无法作为表达式的解释在Python语言的开发和调试中,有时候会遇到“关键字无法作为表达式”的错误。这个错误的前提是程序代码中出现了Python中已经使用的关键字,如if、for、while、import等等。在这些关键字被用于变量、函数名或其他上下文环境时,Python解释器就会抛出这种错误。

    2023-12-11
    65
  • Excel中的字符串截取,以从文件路径中截取文件名为例[亲测有效]

    Excel中的字符串截取,以从文件路径中截取文件名为例[亲测有效]在之前的文章《Excel中如何将两个文本合并在一起?》中给大家分享过如何合并文本,今天这篇文章分享一下如何从一个文本中截取出一部分。比如从一个文

    2023-03-01
    96

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注