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

开源OpenGauss数据库中事务管理源码解析

原创 awei 2021-12-06
701

开源OpenGauss数据库中事务管理源码解析

一、 事务状态机

openGauss将事务系统分为上层(事务块TBlockState)以及底层(TransState)两个层次。(代码位于src/gausskernel/storage/access/transam/xact.cpp)

  1. 上层事务块:客户端query的状态,用于提高用户操作数据的灵活性,用事务块的形式支持在一个事务中执行多条query语句。

    事务块状态机:

    每个事务状态都对应一个事务状态机结构体。
    在无异常情形下,一个事务块的状态机如上图所示按照默认(TBLOCK_DEFAULT)->已开始(TBLOCK_STARTED)->事务块开启(TBLOCK_BEGIN)->事务块运行中(TBLOCK_INPROGRESS)->事务块结束(TBLOCK_END)->默认(TBLOCK_DEFAULT)循环。剩余的状态机是在上述正常场景下的各个状态点的异常处理分支。

    在事务块运行中(TBLOCK_INPROGRESS)出错分为2种情形。事务执行失败:事务块运行中(TBLOCK_INPROGRESS)->回滚(TBLOCK_ABORT)->回滚结束(TBLOCK_ABORT_END)->默认(TBLOCK_DEFAULT);用户手动回滚执行成功的事务:事务块运行中(TBLOCK_INPROGRESS)->回滚等待(TBLOCK_ABORT_PENDING)->默认(TBLOCK_DEFAULT)。

  2. 底层(TransState):从内核视角的事务状态,真正意义上的事务状态。

    事务底层状态:

    内核内部底层状态如上图所示,底层状态机的描述见结构体TransState。在事务开启前事务状态为TRANS_DEFAULT。

    事务开启过程中事务状态为TRANS_START。

    事务成功开启后一直处于TRANS_INPROGRESS。

    事务结束/回滚的过程中为TARNS_COMMIT/ TRANS_ABORT。

    事务结束后事务状态回到TRANS_DEFAULT。

二、 事务状态机系统实例

BEGIN;

SELECT \* FROM TABLE1;

END;

1. 整体流程

任何语句的执行总是先进入事务处理接口事务块中,然后调用事务底层函数处理具体命令,最后返回到事务块中。

2. BEGIN执行流程

(1) 通过入口函数exec_simple_query处理begin命令。(函数位于\openGauss-server-master\src\gausskernel\process\tcop\postgres.cpp)
static void exec\_simple\_query(const char\* query\_string, MessageType messageType, StringInfo msg = NULL)
该函数添加默认参数unint16 messageType。其默认值为0。如果我们收到混合消息,该参数将设置为1,以告诉我们正常查询字符串后跟信息字符串。query_string = normal querystring + message
begin的query_string=0x1002cd0”begin;”
然后我们将meesageType与1进行比较。当messageType为1时,表示此消息是混合消息。查询字符串后面是一些我们必须处理的信息。我们将查询字符串分为两部分,普通查询字符串和信息字符串。然后主要调用 start_xact_command();

(void)PortalRun(portal, FETCH_ALL, isTopLevel, receiver, receiver, completionTag);

finish_xact_command();

(2) start_xact_command函数开始一个query命令,调用StartTransactionCommand函数,此时事务块上层状态未TBLOCK_DEFAULT,继续调用StartTransaction函数,设置事务底层状态TRANS_START,完成内存、缓存区、锁资源的初始化后将事务底层状态设为TRANS_INPROGRESS,最后在StartTransactionCommand函数中设置事务块上层状态为TBLOCK_STARTED。

TRANS\_DEFAULT->TRANS\_START->TRANS\_INPROGRESS

TBLOCK\_DEFAULT->TBLOCK\_STARTED

TRANS\_DEFAULT->TRANS\_START->TRANS\_INPROGRESS

TBLOCK\_DEFAULT->TBLOCK\_STARTED

TRANS\_DEFAULT->TRANS\_START->TRANS\_INPROGRESS

TBLOCK\_DEFAULT->TBLOCK\_STARTED


(3) PortalRun处理begin语句



(4) finish_xact_command


finish_xact_command函数结束一个query命令,调用CommitTransactionCommand函数设置事务块上层状态从TBLOCK_BEGIN变为TBLOCK_INPROGRESS,并等待读取下一条命令。

  1. Select语句流程

    (1) exec_simple_query select 的 query_string=0x1002cd0"SELECT * FROM table1;"

    (2) start_xact_command调用StartTransactionCommand函数,由于当前上层事务块状态为TBLOCK_INPROGRESS,说明已经在事务块内部,则直接返回,不改变事务上层以及底层的状态。

    (3) PortalRun:依次向下调用函数ExecutorRun根据执行计划执行最优路径查询。

(4) finish_xact_command 调用CommitTransactionCommand函数,当前事务块上层状态仍为TBLOCK_INPROGESS,不改变当前事务上层以及底层的状态。

  1. Begin语句流程

    (1) exec_simple_query end 的 query_string=0x1002cd0"end;"

    (2) start_xact_command调用StartTransactionCommand函数,由于当前上层事务块状态为TBLOCK_INPROGRESS,说明已经在事务块内部,则直接返回,不改变事务上层以及底层的状态。

    (3) PortalRun 设置事务块上层状态为TBLOCK_END。

    (4) finish_xact_command 设置事务底层状态为TRANS_COMMIT,进行事务提交流程并且清理事务资源;清理后设置底层事务状态为TRANS_DEFAULT


    继续调用CommitTransaction函数提交事务,设置事务底层状态为TRANS_COMMIT,进行事务提交流程并且清理事务资源;本地持久化CLOG及XLOG日志,并清空相应的事务槽位信息。清理后设置底层事务状态为TRANS_DEFAULT,返回CommitTansactionCommand函数;设置事务块上层状态为TBLOCK_DEFAULT,整个事务块结束。

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

评论