閱讀311 返回首頁    go 阿裏雲 go 技術社區[雲棲]


GTS for DRDS分布式事務的實現理解

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;

最後更新:2017-09-20 18:02:52

  上一篇:go  9月20日雲棲精選夜讀:異構計算&高性能計算分論壇——揭秘拿什麼實現超算平民化、國際化?
  下一篇:go  會玩超級瑪麗,機器學習能有多難?