TiDB 事务心跳超时机制测试
source link: https://blog.51cto.com/tidb/9581397
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
TiDB 事务心跳超时机制测试
精选 原创作者: yiduoyunQ
当 APP ”同时“ 发送 txn1 和 txn2 到 TiDB,txn1 和 txn2 之间存在锁冲突,TiDB 先执行了 txn1,则 txn2 需要等到 txn1 提交或回滚之后才能执行,TiDB 内部通过事务心跳机制来防止一些特殊情况下 txn1 持有锁的泄漏,进而防止 txn2 无限期等待。当 txn1 事务心跳超时后,txn2 即可 resolve txn1 持有的锁,之后当 txn1 恢复后会 rollback 并返回 error 报错给 APP。
常见的事务心跳超时情况有:
- txn 运行的 TiDB 与 TiKV 网络失联(本文模拟场景)。
- TiKV busy 导致 TiDB 发送心跳失败超时,TiDB 会自动 retry。
本文测试场景
场景1: txn1 和 txn2 锁相同数据,txn1 心跳超时,lock 被 txn2 resolved,txn1 commit 失败,txn2 commit 成功。
场景2: txn1 和 txn2 锁不同数据,txn1 心跳超时后恢复,txn1 & txn2 commit 成功。
场景1: txn1 和 txn2 之间存在锁冲突,txn1 心跳超时后,txn2 resolve lock,txn1 心跳超时恢复后在 commit 阶段失败回滚。
场景2: txn1 和 txn2 之间没有锁冲突,txn1 心跳超时恢复后可以继续发送,commit 成功。
PS:不加锁语句如简单 select 不存在事务锁冲突,不在本文测试范围内,大家感兴趣可以自行测试更多语句模式。
- 使用 Kind + Operator 部署 TiDB 集群
- 使用 Chaos Mesh 模拟网络分区
- Operator v1.5.2
- TiDB cluster v5.1.5 (所有版本适用)
- Chaos Mesh v2.6.2
<!---->
id 为主键 handle key
mysql> select * from t;
+----+------+
| id | c |
+----+------+
| 1 | a |
| 2 | b |
| 3 | c |
+----+------+
3 rows in set (0.01 sec)
场景1 事务心跳超时 & 锁相同 row id
- SessionA on tidb-0 start transaction on
t.id = 1
begin;
select * from t where id = 1 for update;
tidb-0 periodically sends txn heartbeat to TiKV
- Simulate network partition between tidb-0 and all tikv
- During Simulation SessionB on tidb-1 select on
t.id = 1
begin;
select * from t where id = 1 for update;
tidb-1 periodically sends txn heartbeat to TiKV
- Stop Simulation
tidb-0 can not continue sending heartbeat to TiKV
- SessionA on tidb-0 continue transaction and commit return KV error
update t set c = 'aa' where id = 1;
commit;
- SessoinB on tidb-1 execute transaction successfully
update t set c = 'aa' where id = 1;
commit;
场景2 事务心跳超时 & 锁不同 row id
- Session A on tidb-0 start transaction on
t.id = 1
begin;
select * from t where id = 1 for update;
tidb-0 periodically sends heartbeat to TiKV
- Simulate network partition between tidb-0 and all tikv
- During Simulation SessionB on tidb-1 select on
t.id = 2
begin;
select * from t where id = 2 for update;
tidb-1 periodically sends heartbeat to TiKV
- Stop Simulation
tidb-0 can continue sending heartbeat to TiKV
- SessionA on tidb-0 continues transaction successfully
update t set c = 'aa' where id = 1;
commit;
- SessoinB on tidb-1 continues transaction successfully
update t set c = 'bb' where id = 2;
commit;
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK