GTS for DRDS分布式事务的实现理解

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

GTS介绍

全局事务服务(Global Transaction Service,简称 GTS)是一款高性能、高可靠、接入简单的分布式事务中间件,用于解决分布式环境下的数据一致性问题。

一个完整的业务往往需要调用多个子业务或服务,随着业务的不断增多,涉及的服务及数据也越来越多,越来越复杂。传统的系统难以支撑,出现了应用和数据库等的分布式系统。分布式系统又带来了数据一致性的问题,从而产生了分布式事务。

分布式事务是指事务发起者、资源管理器、事务协调者及资源分别位于不同的分布式系统的不同节点之上。

GTS 的架构如下图所示:

1ebcd6f1719dc20224b4c869164881c4222575a4

ü  GTS 服务端:即事务协调器。负责分布式事务的推进,管理事务生命周期。

ü  GTS 客户端:即事务发起者。通过事务协调器,开启、提交、回滚分布式事务。同时还包含部分资源管理器组件,负责管理和控制资源,与 GTS 服务器进行交互。

ü  服务框架:GTS 可以和 EDAS 等服务框架配合使用,管理服务框架中的事务。服务框架可以集成资源管理器组件,管理和控制资源。

ü  资源: 包括RDS、DRDS、MySQL以及其它数据库事务,还包括 MQ 消息事务

在单机数据库下很容易维持事务的 ACID(Atomicity、Consistency、Isolation、Durability)特性,但在分布式系统中并不容易,GTS 可以保证分布式系统中的分布式事务的 ACID 特性。

GTS 支持 DRDS、RDS、MySQL 等多种数据源,可以配合 EDAS 和 Dubbo 等微服务框架使用, 兼容 MQ 实现事务消息。通过各种组合,可以轻松实现分布式数据库事务、多库事务、消息事务、服务链路级事务等多种业务需求

 

GTS解决使用 DRDS 进行分库分表后产生的跨分库事务问题

DRDS 通过分库分表实现数据水平拆分, 来解决单机关系型数据库扩展性问题. 但是原有单库单表进行分库分表后, 单表的数据被分散到多个库的表中, 原来对单表多行数据进行的变更, 可能会变为对多库多表的数据变更,即单机本地事务变成了分布式事务。

DRDS 本身不支持分布式事务, 上述场景下再采用原来的单库事务进行操作会导致失败。在 DRDS 中加入 GTS 能够实现这种多个库交易操作的原子性,解决分布式数据库跨库事务的问题

47ec6ac3a44773123b5e14c4a86f2d994192d586

应用端使用分布式事务流程,手工处理事务的典型 SQL 语句步骤如下:

1.set autocommit=false //开启事务

2.select last_txc_xid() //注册一个 GTS 事务

3.insert/update/delete 等业务 SQL

4.commit 或者 rollback //全局提交或回滚

5.autocommit=true //恢复自动提交

 

通过后端RDS的SQL审计可以查看到在分布式事务情况下分库的处理过程:

 

插入类型:

序号

SQL明细

1

SET autocommit=0

2

select * from `USER_TBL` limit 1

3

SHOW FULL TABLES FROM `marcotest_iirz_0004` LIKE 'user_tbl'

4

SHOW FULL COLUMNS FROM `user_tbl` FROM `marcotest_iirz_0004` LIKE '%'

5

SHOW INDEX FROM `user_tbl` FROM `marcotest_iirz_0004`

6

/* 0aacc85e15058276714612682d3f81/9// *//*DRDS /11.193.54.46/bc105690c801000-d/ */insert into `user_tbl` ( `u_id`, `u_name`, `u_phone`, `u_national`, `createtime`, `updatetime`) values ( 7927652, 'marco7809361834', '8874414727236', 'China-RDS000', '2017-07-09 21:42:50', '2017-07-09 21:42:50')

7

SELECT `USER_TBL`.U_PHONE,`USER_TBL`.U_NAME,`USER_TBL`.U_NATIONAL,`USER_TBL`.CREATETIME,`USER_TBL`.U_ID,`USER_TBL`.UPDATETIME FROM `USER_TBL` WHERE user_tbl.U_ID = 7927652

8

INSERT INTO txc_undo_log(id, xid, branch_id, rollback_info, gmt_create, gmt_modified, status, server) VALUES(769948877,'10.152.29.148:8091:769948876',769948877,'{\"branchId\":769948877,\"id\":0,\"info\":[{\"frontImage\":{\"line\":[],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"rearImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7809361834\"},{\"name\":\"U_NATIONAL\",\"type\":12,\"value\":\"China-RDS000\"},{\"name\":\"CREATETIME\",\"type\":93,\"value\":\"1499607770000\"},{\"name\":\"U_ID\",\"type\":4,\"value\":7927652},{\"name\":\"UPDATETIME\",\"type\":93,\"value\":\"1499607770000\"}]}],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"selectSql\":\"SELECT `USER_TBL`.U_PHONE,`USER_TBL`.U_NAME,`USER_TBL`.U_NATIONAL,`USER_TBL`.CREATETIME,`USER_TBL`.U_ID,`USER_TBL`.UPDATETIME FROM `USER_TBL`\",\"sql\":\"/* 0aacc85e15058276714612682d3f81/9// *//*DRDS /11.193.54.46/bc105690c801000-d/ */insert into `user_tbl` ( `u_id`, `u_name`, `u_phone`, `u_national`, `createtime`, `updatetime`) values ( 7927652, \'marco7809361834\', \'8874414727236\', \'China-RDS000\', \'2017-07-09 21:42:50\', \'2017-07-09 21:42:50\') \",\"sqlType\":\"INSERT\",\"whereCondition\":\" WHERE U_ID=7927652\"}],\"rT\":31553,\"rTFromLastPoint\":1,\"registBranch\":true,\"server\":\"10.152.29.148:8091\",\"status\":0,\"writeKeys\":\"user_tbl:7927652\",\"xid\":\"10.152.29.148:8091:769948876\"}',now(),now(),0,'10.152.29.148:8091') ON DUPLICATE KEY UPDATE id = 769948877,xid = '10.152.29.148:8091:769948876',branch_id = 769948877,rollback_info = '{\"branchId\":769948877,\"id\":0,\"info\":[{\"frontImage\":{\"line\":[],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"rearImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7809361834\"},{\"name\":\"U_NATIONAL\",\"type\":12,\"value\":\"China-RDS000\"},{\"name\":\"CREATETIME\",\"type\":93,\"value\":\"1499607770000\"},{\"name\":\"U_ID\",\"type\":4,\"value\":7927652},{\"name\":\"UPDATETIME\",\"type\":93,\"value\":\"1499607770000\"}]}],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"selectSql\":\"SELECT `USER_TBL`.U_PHONE,`USER_TBL`.U_NAME,`USER_TBL`.U_NATIONAL,`USER_TBL`.CREATETIME,`USER_TBL`.U_ID,`USER_TBL`.UPDATETIME FROM `USER_TBL`\",\"sql\":\"/* 0aacc85e15058276714612682d3f81/9// *//*DRDS /11.193.54.46/bc105690c801000-d/ */insert into `user_tbl` ( `u_id`, `u_nam

9

commit

10

SET autocommit=1

11

delete from txc_undo_log where id = 769948877

 

更新类型:

序号

SQL明细

1

SET autocommit=0

2

select * from USER_TBL limit 1

3

SHOW FULL TABLES FROM `marcotest_iirz_0004` LIKE 'user_tbl'

4

SHOW FULL COLUMNS FROM `user_tbl` FROM `marcotest_iirz_0004` LIKE '%'

5

SHOW INDEX FROM `user_tbl` FROM `marcotest_iirz_0004`

6

SELECT USER_TBL.U_PHONE,USER_TBL.U_NAME,USER_TBL.U_NATIONAL,USER_TBL.CREATETIME,USER_TBL.U_ID,USER_TBL.UPDATETIME FROM USER_TBL WHERE USER_TBL.`u_id` = 7927652 FOR UPDATE

7

/* 0aacc85e15058261818692667d3f81/9// *//*DRDS /11.193.54.46/bc0ffc01f801000-d/ */update `user_tbl` set `u_national` = 'China-RDS000--' where (`u_id` = 7927652)

8

SELECT USER_TBL.U_PHONE,USER_TBL.U_NAME,USER_TBL.U_NATIONAL,USER_TBL.CREATETIME,USER_TBL.U_ID,USER_TBL.UPDATETIME FROM USER_TBL WHERE U_ID=7927652

9

INSERT INTO txc_undo_log(id, xid, branch_id, rollback_info, gmt_create, gmt_modified, status, server) VALUES(969949165,'10.152.29.138:8091:969949163',969949165,'{\"branchId\":969949165,\"id\":0,\"info\":[{\"frontImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7809361834\"},{\"name\":\"U_NATIONAL\",\"type\":12,\"value\":\"China-RDS000\"},{\"name\":\"CREATETIME\",\"type\":93,\"value\":\"1499607770000\"},{\"name\":\"U_ID\",\"type\":4,\"value\":7927652},{\"name\":\"UPDATETIME\",\"type\":93,\"value\":\"1499607770000\"}]}],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"rearImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7809361834\"},{\"name\":\"U_NATIONAL\",\"type\":12,\"value\":\"China-RDS000--\"},{\"name\":\"CREATETIME\",\"type\":93,\"value\":\"1499607770000\"},{\"name\":\"U_ID\",\"type\":4,\"value\":7927652},{\"name\":\"UPDATETIME\",\"type\":93,\"value\":\"1505826181000\"}]}],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"selectSql\":\"SELECT USER_TBL.U_PHONE,USER_TBL.U_NAME,USER_TBL.U_NATIONAL,USER_TBL.CREATETIME,USER_TBL.U_ID,USER_TBL.UPDATETIME FROM USER_TBL\",\"sql\":\"/* 0aacc85e15058261818692667d3f81/9// *//*DRDS /11.193.54.46/bc0ffc01f801000-d/ */update `user_tbl` set `u_national` = \'China-RDS000--\' where (`u_id` = 7927652)\",\"sqlType\":\"UPDATE\",\"whereCondition\":\" WHERE U_ID=7927652\"}],\"rT\":19155,\"rTFromLastPoint\":0,\"registBranch\":true,\"server\":\"10.152.29.138:8091\",\"status\":0,\"writeKeys\":\"user_tbl:7927652\",\"xid\":\"10.152.29.138:8091:969949163\"}',now(),now(),0,'10.152.29.138:8091') ON DUPLICATE KEY UPDATE id = 969949165,xid = '10.152.29.138:8091:969949163',branch_id = 969949165,rollback_info = '{\"branchId\":969949165,\"id\":0,\"info\":[{\"frontImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7809361834\"},{\"name\":\"U_NATIONAL\",\"type\":12,\"value\":\"China-RDS000\"},{\"name\":\"CREATETIME\",\"type\":93,\"value\":\"1499607770000\"},{\"name\":\"U_ID\",\"type\":4,\"value\":7927652},{\"name\":\"UPDATETIME\",\"type\":93,\"value\":\"1499607770000\"}]}],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"rearImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7

10

commit

11

SET autocommit=1

12

delete from txc_undo_log where id = 969949165

 

删除类型:

序号

SQL明细

1

SET autocommit=0

2

select * from `USER_TBL` limit 1

3

SHOW FULL TABLES FROM `marcotest_iirz_0004` LIKE 'user_tbl'

4

SHOW FULL COLUMNS FROM `user_tbl` FROM `marcotest_iirz_0004` LIKE '%'

5

SHOW INDEX FROM `user_tbl` FROM `marcotest_iirz_0004`

6

SELECT `USER_TBL`.U_PHONE,`USER_TBL`.U_NAME,`USER_TBL`.U_NATIONAL,`USER_TBL`.CREATETIME,`USER_TBL`.U_ID,`USER_TBL`.UPDATETIME FROM `USER_TBL` WHERE `USER_TBL`.`u_id` = 7927652 FOR UPDATE

7

/* 0aacc85e15058271185702675d3f81/9// *//*DRDS /11.193.54.46/bc10169d0401000-27/ */delete from `user_tbl` where (`u_id` = 7927652)

8

INSERT INTO txc_undo_log(id, xid, branch_id, rollback_info, gmt_create, gmt_modified, status, server) VALUES(869948781,'10.152.29.56:8091:869948780',869948781,'{\"branchId\":869948781,\"id\":0,\"info\":[{\"frontImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7809361834\"},{\"name\":\"U_NATIONAL\",\"type\":12,\"value\":\"China-RDS000--\"},{\"name\":\"CREATETIME\",\"type\":93,\"value\":\"1499607770000\"},{\"name\":\"U_ID\",\"type\":4,\"value\":7927652},{\"name\":\"UPDATETIME\",\"type\":93,\"value\":\"1505826181000\"}]}],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"rearImage\":{\"line\":[],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"selectSql\":\"SELECT `USER_TBL`.U_PHONE,`USER_TBL`.U_NAME,`USER_TBL`.U_NATIONAL,`USER_TBL`.CREATETIME,`USER_TBL`.U_ID,`USER_TBL`.UPDATETIME FROM `USER_TBL`\",\"sql\":\"/* 0aacc85e15058271185702675d3f81/9// *//*DRDS /11.193.54.46/bc10169d0401000-27/ */delete from `user_tbl` where (`u_id` = 7927652)\",\"sqlType\":\"DELETE\",\"whereCondition\":\" WHERE U_ID=7927652\"}],\"rT\":40160,\"rTFromLastPoint\":1,\"registBranch\":true,\"server\":\"10.152.29.56:8091\",\"status\":0,\"writeKeys\":\"user_tbl:7927652\",\"xid\":\"10.152.29.56:8091:869948780\"}',now(),now(),0,'10.152.29.56:8091') ON DUPLICATE KEY UPDATE id = 869948781,xid = '10.152.29.56:8091:869948780',branch_id = 869948781,rollback_info = '{\"branchId\":869948781,\"id\":0,\"info\":[{\"frontImage\":{\"line\":[{\"fields\":[{\"name\":\"U_PHONE\",\"type\":12,\"value\":\"8874414727236\"},{\"name\":\"U_NAME\",\"type\":12,\"value\":\"marco7809361834\"},{\"name\":\"U_NATIONAL\",\"type\":12,\"value\":\"China-RDS000--\"},{\"name\":\"CREATETIME\",\"type\":93,\"value\":\"1499607770000\"},{\"name\":\"U_ID\",\"type\":4,\"value\":7927652},{\"name\":\"UPDATETIME\",\"type\":93,\"value\":\"1505826181000\"}]}],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"rearImage\":{\"line\":[],\"schemaName\":\"marcotest_iirz_0004\",\"tableName\":\"user_tbl\"},\"selectSql\":\"SELECT `USER_TBL`.U_PHONE,`USER_TBL`.U_NAME,`USER_TBL`.U_NATIONAL,`USER_TBL`.CREATETIME,`USER_TBL`.U_ID,`USER_TBL`.UPDATETIME FROM `USER_TBL`\",\"sql\":\"/* 0aacc85e15058271185702675d3f81/9// *//*DRDS /11.193.54.46/bc10169d0401000-27/ */delete from `user_tbl` where (`u_id` = 7927652)\",\"sqlType\":\"DELETE\",\"whereCondition\":\" WHERE U_ID=7927652\"}],\"rT\":40160,\"rTFromLastPoint\":0,\"registBranch\":true,\"server\":\"10.152.29.56:8091\",\"s

9

commit

10

SET autocommit=1

11

delete from txc_undo_log where id = 869948781

 

客户端发起分布式事务的时候会获取一个全局事务ID,每个分库的任何更新操作前会发起分支事务或者BranchID,任何进行更新操作,当前客户端发起全局提交时,GTS会对每个分库的undo_log表插入回滚信息,然后提交(如果任一分库提交失败,使用回滚信息进行回滚操作);等所有分库提交成功后,在删除所有分库的回滚信息;

回滚信息主要是通过查询表结构元数据及通过主键来查询更新前后的行数据,所有使用GTS分布式事务涉及的表一定要有主键;

 

 

可以看看txc_undo_log表结构,在每个分库都会有一张:

fa2f575136d4baa7e2fbb98aa2b02006309ddabc

XID:XID,即 GTS 分布式事务的全局事务 ID,GTS 服务会为每一个分布式事务生成一个全局唯一的分布式事务 ID

Branch_ID:GTS 分布式事务的分支事务 ID,它是事务分支的唯一标识。XID 和 BranchId 是一对多的包含关系,即一个全局事务可能包含多个事务分支

rollback_info:回滚信息,主要是保存UNDO LOG;

相关实践学习
Polardb-x 弹性伸缩实验
本实验主要介绍如何对PolarDB-X进行手动收缩扩容,了解PolarDB-X 中各个节点的含义,以及如何对不同配置的PolarDB-x 进行压测。
目录
相关文章
|
6月前
|
SQL 存储 Web App开发
PolarDB-X 分布式数据库中的外键
外键是关系型数据库中非常便利的一种功能,它通过一个或多个列为两张表建立连接,从而允许跨表交叉引用相关数据。外键通过约束来保持数据的一致性,通过级联来同步数据在多表间的更新和删除。在关系数据库系统中,大多数表都遵循外键的概念。
|
9天前
|
Docker 容器 关系型数据库
【PolarDB-X从入门到精通】 第四讲:PolarDB分布式版安装部署(源码编译部署)
本期课程将于4月11日19:00开始直播,内容包括源码编译基础知识和实践操作,课程目标是使学员掌握源码编译部署技能,为未来发展奠定基础,期待大家在课程中取得丰富的学习成果!
【PolarDB-X从入门到精通】 第四讲:PolarDB分布式版安装部署(源码编译部署)
|
4月前
|
存储 关系型数据库 MySQL
[重磅更新]PolarDB-X V2.3 集中式和分布式一体化开源发布
2023年云栖大会,PolarDB-X 正式发布 2.3.0版本,重点推出PolarDB-X标准版(集中式形态),将PolarDB-X分布式中的DN节点提供单独服务,支持paxos协议的多副本模式、lizard分布式事务引擎,可以100%兼容MySQL。同时在性能场景上,采用生产级部署和参数(开启双1 + Paxos多副本强同步),相比于开源MySQL 8.0.34,PolarDB-X在读写混合场景上有30~40%的性能提升,可以作为开源MySQL的最佳替代选择。
|
3月前
|
存储 SQL 关系型数据库
贝泰妮使用PolarDB-X构建OMS分布式订单系统
贝泰妮使用PolarDB-X构建OMS分布式订单系统
|
5月前
|
存储 关系型数据库 MySQL
PolarDB-X V2.3 集中式和分布式一体化开源发布
本文主要介绍PolarDB-X V2.3 集中式和分布式一体化开源。
|
7月前
|
存储 关系型数据库 MySQL
PolarDB-X 存储引擎核心技术 | Lizard分布式事务系统
关系型数据库作为支撑企业级数据的在线存储方案,发挥了无可替代的作用。随着海量数据的增长,以及面对创新业务爆发性增长的场景,如何能够快速,业务无损的进行在线数据库扩容,对数据库的架构提出了巨大的挑战,除此以外,企业的精细化经营,也要求数据库能够一站式提供事务处理能力和数据分析能力,为了应对这些挑战,分布式数据库应运而生。
|
SQL 存储 弹性计算
ACP互联网架构认证笔记 DRDS分布式关系型数据库服务
DRDS的基础原理是Sharding,即数据分片,是典型的水平扩展分布式数据库模型,和传统单机数据库share anything架构不同,DRDS采用的是share nothing架构。
398 0
|
10月前
|
SQL Kubernetes Cloud Native
云原生数据库PolarDB分布式版(PolarDB-X)原理导读
由于PolarDB-X相关文档比较丰富,知识点分布广泛,因此我专门整理一篇导读文章帮助大家更有节奏有方向的学习。本文所推荐文章会按照由浅入深的顺序,并且每个知识点前都会进行提问,大家可以带着问题进入章节学习。最后希望大家都能领会到分布式数据库的魅力。
|
11月前
|
SQL 算法 前端开发
开源分布式数据库PolarDB-X源码解读——PolarDB-X源码解读(六):分布式死锁检测
开源分布式数据库PolarDB-X源码解读——PolarDB-X源码解读(六):分布式死锁检测
327 0
|
12月前
|
SQL 存储 容灾
PolarDB-X 致数据库行内人 (一) ~ 如何有效评测国产数据库的分布式事务
本文是系列文章的第一篇,介绍第一个重要话题:“数据库的分布式事务”,这也是目前普通用户面对分布式数据库产品介绍问的最多的一个内容,如何有效评测分布式事务也是一个非常重要的能力。致敬同行,我们将PolarDB-X事务架构设计上的一些思考和测试方式,做了整理和梳理,期望能对大家更好的理解分布式事务的测试有所帮助。