作者: pepezzzz 原文来源:https://tidb.net/blog/f80362b4
背景
在分布式数据库的选型和测试过程中,通常需要关注分布式事务在高可用场景下的一致性和 RPO=0 的容灾技术实现。分布式事务需要能影响多张表的多条记录,实现多表事务和跨节点高可用的验证。
BANK 程序
BANK 程序(链接: https://pan.baidu.com/s/1M14Kf0ULGdbkoMZj0iOvDA?pwd=p93k 提取码: p93k)是一个简化转账模型的并发程序。初始化后,会创建流水 record 表和账务 account 表,流水表对应转账过程中的金额变化和事务时间( tso 列,实际函数为 time.Now().UnixNano() ,即执行节点的纳秒时间),account 表记录最终的账户金额和事务时间(tso 列),record 表和 account 表的同一事务(tso 列) 的交易记录和交易账户能对应。
MySQL [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| accounts |
| record |
+----------------+
2 rows in set (0.00 sec)
MySQL [test]> select * from record order by tso desc limit 1;
+---------+-------+--------------+--------------------+------------+------------------+--------+---------------------+
| from_id | to_id | from_balance | from_balance_after | to_balance | to_balance_after | amount | tso |
+---------+-------+--------------+--------------------+------------+------------------+--------+---------------------+
| 384 | 172 | 1226 | 284 | 1915 | 2857 | 942 | 1661398293659372259 |
MySQL [test]> select * from accounts order by tso desc limit 10;
+-----+---------+---------------------------------------------------------------------------------------------------+---------------------+
| id | balance | remark | tso |
+-----+---------+---------------------------------------------------------------------------------------------------+---------------------+
| 384 | 284 | abcdefghijklmnopqrs | 1661398293659372259 |
| 172 | 2857 | abcdefg | 1661398293659372259 |
复制代码
使用方法
程序的参数如下:
[root@iZuf6d7xln13sovvijl68rZ ~]# ./bank --help
Usage of ./bank:
-accounts int
the number of the bank accounts (default 1000000)
-create
create new tables for test
-driver string
database driver name, support 'mysql', 'postgres' (default "mysql")
-dsn string
data source name
MySQL: root:@tcp(127.0.0.1:4000)/test
PostgreSQL: postgres://root:@127.0.0.1:5432/postgres?sslmode=disable
(default "root:@tcp(127.0.0.1:4000)/test")
-insert
insert data for test
-interval duration
verify interval (default 2s)
-threads int
threads count (default 10)
复制代码
初次执行
./bank -dsn 'root:password@tcp(172.16.5.31:34000)/test' -create -insert -accounts 100
复制代码
配好 DSN 后,第一次执行程序添加 -create -insert 参数会自动初始化数据,初始完成后开始转账,就随机挑选两个账户,select for update 锁定账户,然后 update 账户并记录流水,然后提交事务。
中断后可后续执行
./bank -dsn 'root:password@tcp(172.16.5.31:34000)/test' -accounts 100
复制代码
bank 程序除转账交易的并发线程(默认 10 个)外,有一个 goroutine,到达校验 interval (默认 2 秒)时间就会算一下账户总金额是不是对的,不是预期的就退出。
使用场景
节点高可用情况等情况下的事务一致性。如果总金额不一致,说明发生事务破裂。
RPO=0 容灾场景的数据一致性。如果最新的 TSO 不一致,说明不是 RPO=0。
逻辑复制场景的历史数据一致性。如果历史 TSO 的数据不一致,说明复制过程数据不一致。
评论