PostgreSQL源码学习调度器#13

database

本节介绍PortalRunMulti函数。

PortalRunMulti函数

static void

PortalRunMulti(Portal portal,

bool isTopLevel, bool setHoldSnapshot,

DestReceiver *dest, DestReceiver *altdest,

char *completionTag);

//src/backend/tcop/pquery.c

/* 若目标是DestRemoteExecute,则设置为DestNone */

if (dest->mydest == DestRemoteExecute)

dest = None_Receiver;

if (altdest->mydest == DestRemoteExecute)

altdest = None_Receiver;

/* 依次处理每个计划 */

foreach(stmtlist_item, portal->stmts)

{

PlannedStmt *pstmt = lfirst_node(PlannedStmt, stmtlist_item);

/* 检查取消信号 */

CHECK_FOR_INTERRUPTS();

/* 若是DML语句 */

if (pstmt->utilityStmt == NULL)

{

/* 动态追踪中当一个查询的规划被开始时触发的探针 */

TRACE_POSTGRESQL_QUERY_EXECUTE_START();

/* 若有需要,在这里重置执行器计时 */

if (log_executor_stats)

ResetUsage();

/* 第一次创建一个新快照,后续更新快照副本的计数就可以 */

if (!active_snapshot_set)

{

Snapshot snapshot = GetTransactionSnapshot();

/* 有需要时,注册快照并保存在portal中 */

if (setHoldSnapshot)

{

snapshot = RegisterSnapshot(snapshot);

portal->holdSnapshot = snapshot;

}

/* 不可以让一个holdSnapshot同时也是一个activeSnapshot,因此这里会拷贝一次 */

PushCopiedSnapshot(snapshot);

active_snapshot_set = true;

}

UpdateActiveSnapshotCommandId();

/* 处理DML的query语句(上节讲过) */

if (pstmt->canSetTag)

{

/* 语句会设置completionTag */

ProcessQuery(pstmt,

portal->sourceText,

portal->portalParams,

portal->queryEnv,

dest, completionTag);

}

else

{

/* 语句是rewrite阶段增加的,不会设置completionTag */

ProcessQuery(pstmt,

portal->sourceText,

portal->portalParams,

portal->queryEnv,

altdest, NULL);

}

/* 若有需要,在这里完成执行器计时并输出 */

if (log_executor_stats)

ShowUsage("EXECUTOR STATISTICS");

/* 动态追踪中当一个查询的规划结束时触发的探针 */

TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();

}

/* DDL语句 */

else

{

if (pstmt->canSetTag)

{

Assert(!active_snapshot_set);

/* 语句会设置completionTag */

PortalRunUtility(portal, pstmt, isTopLevel, false,

dest, completionTag);

}

else

{

Assert(IsA(pstmt->utilityStmt, NotifyStmt));

/* 语句是rewrite阶段增加的,不会设置completionTag */

PortalRunUtility(portal, pstmt, isTopLevel, false,

altdest, NULL);

}

}

/* 在查询之间增加命令计数器 */

if (lnext(stmtlist_item) != NULL)

CommandCounterIncrement();

/* 清理辅助用的内存上下文 */

Assert(portal->portalContext == CurrentMemoryContext);

MemoryContextDeleteChildren(portal->portalContext);

}

/* 如果刚刚push了快照,现在将其pop */

if (active_snapshot_set)

PopActiveSnapshot();

/* 若没有设置completionTag,使用默认值 */

if (completionTag && completionTag[0] == "")

{

if (portal->commandTag)

strcpy(completionTag, portal->commandTag);

if (strcmp(completionTag, "SELECT") == 0)

sprintf(completionTag, "SELECT 0 0");

else if (strcmp(completionTag, "INSERT") == 0)

strcpy(completionTag, "INSERT 0 0");

else if (strcmp(completionTag, "UPDATE") == 0)

strcpy(completionTag, "UPDATE 0");

else if (strcmp(completionTag, "DELETE") == 0)

strcpy(completionTag, "DELETE 0");

}

以上是 PostgreSQL源码学习调度器#13 的全部内容, 来源链接: utcz.com/z/534183.html

回到顶部