暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

海山数据库(He3DB)源码详解:子事务清理函数

Eric 2024-10-18
80

海山数据库(He3DB)源码详解:子事务清理函数

该函数会在AbortSubTransaction函数之后执行,二者共同完成子事务的中止和清理操作。

执行条件

  1. 在终端主动执行ABORT语句,终止事务会在CommitTransactionCommand函数中调用CleanupSubTransaction函数;

  2. 在隐式事务中执行SQL语句发生错误时,底层源码会跳回PostgresMain函数中并调用AbortCurrentTransaction函数,终止事务并调用CleanupSubTransaction函数。

以下是CleanupSubTransaction函数的执行流程图:
image.png

  1. 开始:流程的开始。
  2. 获取当前事务状态:获取 CurrentTransactionState 以获取当前事务的状态。
  3. 显示事务状态:调用 ShowTransactionState 函数,显示当前事务状态。
  4. 检查事务状态:检查当前事务状态是否不是 TRANS_ABORT
  5. 不是TRANS_ABORT:如果当前事务状态不是 TRANS_ABORT,则记录一条警告日志,说明当前状态。
  6. 是TRANS_ABORT:如果当前事务状态是 TRANS_ABORT,继续执行子事务的清理流程。
  7. 清理子事务门户:调用 AtSubCleanup_Portals 函数,清理子事务的门户(portals)。
  8. 设置当前资源所有者:将当前资源所有者设置为父事务的资源所有者。
  9. 删除子事务资源所有者:如果子事务有自己的资源所有者,调用 ResourceOwnerDelete 函数进行删除。
  10. 清理内存:调用 AtSubCleanup_Memory 函数,进行内存方面的清理。
  11. 设置事务状态为TRANS_DEFAULT:将事务状态设置为 TRANS_DEFAULT,表示子事务已清理。
  12. 弹出当前事务:调用 PopTransaction 函数,从事务堆栈中弹出当前子事务。
  13. 结束:流程结束。

执行过程

1. 开始清理事务

获取当前事务状态并检查。

TransactionState s = CurrentTransactionState; ShowTransactionState("CleanupSubTransaction"); if (s->state != TRANS_ABORT) elog(WARNING, "CleanupSubTransaction while in %s state", TransStateAsString(s->state));
  1. 从全局变量中获得需要终止的事务状态,并记录一条CleanupSubTransaction日志;

  2. 检查当前状态,如果不为TRANS_ABORT调用elog函数记录一条WARNING日志。

2. 清理游标资源

清理子事务创建的所有游标资源。

AtSubCleanup_Portals(s->subTransactionId);

删除子事务失败时创建的所有门户,但注意 不会放弃任何已重新分配给父节点的游标。

3. 清理资源拥有者相关

将父节点移交给全局变量,并释放当前事务资源拥有者。

CurrentResourceOwner = s->parent->curTransactionOwner; CurTransactionResourceOwner = s->parent->curTransactionOwner; if (s->curTransactionOwner) ResourceOwnerDelete(s->curTransactionOwner); s->curTransactionOwner = NULL;
  1. 将父节点的curTransactionOwner移交给全局变量CurrentResourceOwner和CurTransactionResourceOwner;

  2. 如果子事务curTransactionOwner存在,调用ResourceOwnerDelete()函数释放子事务curTransactionOwner资源,并将其置为NULL。

4. 清理内存上下文

将内存上下文切换到父节点,并释放子节点内存上下文。

AtSubCleanup_Memory();
  1. 调用AtSubCleanup_Memory()函数将全局变量CurTransactionContext切换到父节点的curTransactionContext;

  2. 如果TransactionAbortContext存在,清理内存留出空间以备之后使用;

  3. 删除子事务的curTransactionContext,并将其置为NULL。

5. 完成子事务清理

恢复事务的默认状态并从事务链栈弹出子事务。

s->state = TRANS_DEFAULT; PopTransaction();
  1. 将事务状态修改为TRANS_DEFAULT,恢复默状态;

  2. 从事务链栈中弹出子事务,并将顶部事务状态修改为父节点状态。

作者介绍

李超,移动云数据库工程师,负责云原生数据库He3DB的研发。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论