news 2026/5/8 5:08:58

TDSQL分布式事务操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TDSQL分布式事务操作

TDSQL分布式事务操作

图中引入了一个核心组件:Proxy(即图中的中间层),它充当了事务管理器(TM)的角色。


TDSQL 分布式事务执行流程详解

我们将图中的数字编号(1-8)展开,还原整个执行链路:

1. 开启事务 (Step 1)
  • 动作:客户端发送begin指令给 Proxy。
  • 细节:Proxy 在内存中创建一个名为Gtxn (Global Transaction)的数据结构。这个结构体是该事务在分布式环境下的“身份证”,用于记录后续涉及的所有分片(Set)和状态。
2. 第一个 SQL 的路由与 XA 开启 (Step 2, 3, 4)
  • 动作:客户端发送SQL1
  • 细节
    • 解析:Proxy 对 SQL 进行解析,确定数据所在的物理分片(图中为Set 1)。
    • XA Start:由于是该事务第一次访问 Set 1,Proxy 先向 Set 1 发送xa start 'gtid'指令,开启一个全局唯一的事务分支。
    • 执行:接着 Proxy 将具体的SQL1发送给 Set 1 并获得执行结果反馈。
3. 跨分片 SQL 执行 (Step 5)
  • 动作:客户端发送SQL2
  • 细节:Proxy 解析发现SQL2需要访问Set 2。同理,它会向 Set 2 开启 XA 分支并执行。此时,Proxy 的Gtxn结构中已经记录了该事务涉及两个参与者:Set 1 和 Set 2。
4. 触发两阶段提交 (Step 6)
  • 动作:客户端发送Commit
  • 细节:Proxy 接收到提交请求,不会直接让后端提交,而是启动分布式事务 2PC 协议
5. 第一阶段:Prepare 投票 (Step 7)
  • 动作:Proxy 向所有涉及的分片(Set 1, Set 2)并行发送Prepare commit 'gtid'指令。
  • 内部逻辑:各个 Set 收到指令后,将数据修改记录到 Redo Log 且刷盘,同时锁定资源,并回复 Proxy 自己已经准备就绪(Ready)。
6. 关键节点:写入全局事务日志 (Step 8)
  • 动作:Proxy 将事务状态持久化。
  • 细节:当 Proxy 收到所有 Set 的 Ready 回复后,它会在主 Set(图中是 Set 1)的全局事务日志表gtid_log_t中写入一条Commit Log
  • 核心意义
    • 决断点:一旦这条日志写入成功,在逻辑上这个事务就已经成功了。
    • 容灾依据:即便此后 Proxy 宕机,新拉起的 Proxy 只要扫描gtid_log_t发现这条记录,就会强制要求 Set 2 执行最终的 Commit,确保数据不丢失。

技术重点

  • Proxy 的中枢作用:它不仅负责 SQL 路由,还管理着事务的生命周期。Gtxn是内存中的实时状态,而gtid_log_t是磁盘上的最终真相。
  • GTID (Global Transaction ID):图中的'gtid'贯穿始终。它是分布式事务的唯一索引,确保 Proxy、Set 1、Set 2 都在讨论同一件事。
  • 为什么在 Set 1 写日志?:TDSQL 通常选择事务涉及的第一个分片(或者特定的元数据节点)来记录全局日志。这样可以将分布式事务的元数据与业务数据存储在同一个数据库集群中,利用数据库自身的可靠性来保护事务日志。
  • 关于原子性:图中的Step 7是原子性的保证。如果有任何一个 Set 在 Prepare 阶段失败,Proxy 就会走XA ROLLBACK流程,而不会进入 Step 8。

这个流程图展示的是“成功提交”的前半程。在 Step 8 成功后,Proxy 还会发起XA COMMIT指令给所有 Set,完成最后的资源释放。

“Step 8 之后,即使天塌下来,这个事务也得给我提交成功”。这就是分布式事务强一致性的魅力所在。


全局事务示例


xa prepare, insert into … , xa commit三者在物理层面的操作

以下是基于 MySQL 5.7+ 开启binloginnodb_flush_log_at_trx_commit=1sync_binlog=1时的物理执行链路:

第一阶段:XA PREPARE <xid>

目标:将“中间状态”持久化,确保宕机可恢复且主从状态对齐。

  1. Engine: Undo Persistence-> 将用于回滚的 Undo 记录写入Redo Log Buffer
  2. Server: Binlog Event Write-> 在内存中构造XA_prepare_log_event,并写入OS Cache(内存 Binlog 文件)。
  3. Engine: Redo Log Flush (fsync)-> 调用系统fsync,将 Redo Log(含事务状态为PREPARED及 Undo 信息)从 Buffer 强制刷入磁盘物理文件
  4. Server: Binlog Flush (fsync)-> 调用系统fsync,将 Binlog 中的XA_prepare_log_event强制刷入磁盘物理文件
  5. Status: Holding Locks-> 此时在物理内存中,事务涉及的所有行锁(Row Locks)间隙锁继续保持锁定状态,不允许释放。
第二阶段:INSERT INTO xa.gtid_log_t VALUES ('gtid-1')

目标:执行一个标准的本地事务,作为分布式一致性的“逻辑断点”。

  1. Buffer Pool Change-> 在 InnoDB Buffer Pool 中修改gtid_log_t表对应的旧页,生成Dirty Page
  2. Redo Log Write-> 将这一条INSERT操作的物理改动逻辑写入Redo Log Buffer
  3. Binlog Write-> 将此 SQL 对应的逻辑事件(Write_rows_log_event)写入Binlog OS Cache
  4. Two-Phase Flush (Internal)-> 触发一次单机内部的 2PC:
    • fsync Redo Log:确保这条“决策记录”的物理改动已落盘。
    • fsync Binlog:确保这条“决策记录”的逻辑日志已落盘。
  5. Decision Point-> 这一步完成的瞬间,磁盘上已存在gtid-1的持久化记录。此时分布式事务在逻辑上已不可逆转。
第三阶段:XA COMMIT <xid>

目标:修改状态标记,释放物理资源。

  1. Server: Binlog Commit Event-> 在 Binlog 中写入一个XID_log_event(标记该 XID 正式提交),并调用fsync刷盘。
  2. Engine: Memory State Change-> 在 InnoDB 内存事务系统中,将该事务的状态位从PREPARED修改为COMMITTED
  3. Engine: Redo Log Flush (fsync)-> 在 Redo Log 中追加Commit 标记位并调用fsync

    注意:此时数据页(Dirty Page)可能还在内存里,还没刷盘,但这不影响一致性,因为 Redo Log 已落盘。

  4. Engine: Lock Release->最关键动作:遍历该事务所持有的所有锁对象,将其从锁管理器的链表中摘除,唤醒正在等待这些锁的其他线程。
  5. Engine: MVCC Update-> 更新 Read View 相关信息,使得该事务的修改对其他快照读(Snapshot Read)正式可见。
  6. Engine: Undo Purge-> 将该事务的 Undo Log 记录放入Purge 队列,标记为可由后台 GC 线程物理删除。

如果你还记得确保binlog和redolog一致性的XA内部两阶段提交,这里的xa prepare和xa commit与其过程如出一辙。内部两阶段提交的核心逻辑是:先写redolog并prepare,后写binlog并commit。如果commit前宕机,则根据binlog是否写入成功来决定是补上commit还是rollback。这里的xa prepare和xa commit逻辑类似,xa prepare这一步是一个完整的XA内部两阶段提交,包括刷盘redolog和binlog;INSERT INTO xa.gtid_log_t values('xa-gtid-1')这一步,其实类似于XA内部两阶段提交中的,写入binlog的步骤。它的核心含义是,写入一个全局的信息,并以其内容为准,如果后续宕机,通过判断该表中是否有记录,反映本机事务是否执行成功,来决定是commit还是rollback


这样的操作顺序能防止出现什么问题?比如某关键阶段执行失败,会发生什么

场景一:故障发生在“决策点”之前

故障点:Set 1 执行完了XA PREPARE,但在向gtid_log_t插入记录之前,Proxy 挂了。

  • 物理现状
    • Set 1 的磁盘里有Redo(Prep)Binlog(Prep)
    • gtid_log_t表里没有记录。
  • 恢复逻辑
    1. 新 Proxy 接管,扫描所有分片,发现 Set 1 处于PREPARED状态。
    2. 新 Proxy 去查gtid_log_t记录,结果:查无此项
    3. 判决:因为没有全局决策证据,Proxy 命令 Set 1 和 Set 2 执行XA ROLLBACK
  • 防止了什么问题?
    防止了虚假承诺。即使本地已经把日志写好了,但只要没拿到“全局准考证”,就绝对不能提交。这样保证了在 Proxy 意外崩溃时,宁可全部回滚,也不让数据处于不确定的中间态。

场景二:故障发生在“决策点”之后

故障点:插入gtid_log_t成功了,但在执行动作XA COMMIT之前,Set 2 突然宕机了。

  • 物理现状
    • gtid_log_t表里已有记录。
    • Set 1 已准备好,Set 2 还没收到正式提交指令就炸了。
  • 恢复逻辑
    1. Set 2 重启,启动崩溃恢复流程。
    2. Set 2 发现本地有PREPARED事务,但没看到自己的COMMIT标记。
    3. Set 2 并不急着回滚,而是等待指令。
    4. Proxy 扫描到gtid_log_t有记录,立刻向 Set 2 补发XA COMMIT
  • 防止了什么问题?
    防止了半途而废。只要动作 3 写入成功,就相当于在全集群发了一份**“必达令”**。哪怕 Set 2 断电一年,一年后重启,它也必须根据这张“存根”把没干完的活干完(提交),确保 A 扣了钱 B 必须能加上。

场景三:针对“内部 XA”顺序

故障点:在XA PREPARE阶段,动作 1(Redo Prep)写成功了,但在动作 2(Binlog Prep)写入时,磁盘瞬间写满了。

  • 物理现状
    • Redo Log 里记录了修改和XA PREPARED
    • Binlog 里没有任何该事务的记录。
  • 恢复逻辑
    1. MySQL 重启,进行内部对账。
    2. 发现 Redo Log 里有个“待定”事务。
    3. 去翻 Binlog 发现“一片空白”。
    4. 判决:因为 Binlog 没写进去,说明从库(Slave)绝对没收到这笔数据。如果主库提交了,主从就彻底不一致了。
    5. 动作:主库利用 Redo Log 里的 Undo 信息,强制回滚该本地事务。
  • 防止了什么问题?
    防止了主从脱节。这保证了主库的“自愈”始终以“全集群能看到(Binlog)”为准。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 5:08:48

Sanic数据库集成终极指南:异步ORM与连接池配置详解

Sanic数据库集成终极指南&#xff1a;异步ORM与连接池配置详解 【免费下载链接】sanic Accelerate your web app development | Build fast. Run fast. 项目地址: https://gitcode.com/gh_mirrors/sa/sanic Sanic作为一款高性能的Python异步Web框架&#xff0c;凭借其&…

作者头像 李华
网站建设 2026/5/8 5:07:53

Listen gem性能优化终极指南:解决慢速文件监听的7个有效方法

Listen gem性能优化终极指南&#xff1a;解决慢速文件监听的7个有效方法 【免费下载链接】listen The Listen gem listens to file modifications and notifies you about the changes. 项目地址: https://gitcode.com/gh_mirrors/li/listen Listen gem是一款强大的文件…

作者头像 李华
网站建设 2026/5/8 5:07:53

上下文感知技能库:构建智能应用的核心架构与实现

1. 项目概述&#xff1a;一个为开发者赋能的上下文感知技能库最近在GitHub上看到一个挺有意思的项目&#xff0c;叫jamesalmeida/konteks-skill。光看名字&#xff0c;konteks这个词就挺抓眼&#xff0c;它显然是“context”&#xff08;上下文&#xff09;的变体。作为一个在软…

作者头像 李华
网站建设 2026/5/8 4:57:33

STM32简介以及软件安装

目录 1.STM32简介 1. 2.ARM 3.STM32F103C8T6 4.命名规则 5.系统结构​编辑 6.引脚定义​编辑 7.启动配置 8.最小系统电路 2.软件安装 1.安装Keil MDK 2.安装器件支持包 离线下载 在线下载 3.STLINK驱动安装 4.USB转串口的驱动 1.STM32简介 1. 使…

作者头像 李华
网站建设 2026/5/8 4:56:27

zfoo性能优化技巧:10个提升服务器吞吐量的实用方法

zfoo性能优化技巧&#xff1a;10个提升服务器吞吐量的实用方法 【免费下载链接】zfoo &#x1f4a1;Extremely fast enterprise server framework, can be used in RPC, game server, web server. 项目地址: https://gitcode.com/gh_mirrors/zf/zfoo zfoo是一款高性能的…

作者头像 李华
网站建设 2026/5/8 4:47:18

时空智能,镜像视界,国产标杆 物理可信,自主引擎,全域智治

时空智能&#xff0c;镜像视界&#xff0c;国产标杆物理可信&#xff0c;自主引擎&#xff0c;全域智治在数字中国建设持续深化、关键核心技术自主可控上升为国家战略的时代背景下&#xff0c;时空智能已成为数字孪生与视频孪生技术体系的核心底座&#xff0c;更是支撑国家治理…

作者头像 李华