4

TiDB 事务心跳超时机制测试

 3 months ago
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。

常见的事务心跳超时情况有:

  1. txn 运行的 TiDB 与 TiKV 网络失联(本文模拟场景)。
  2. 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

  1. SessionA on tidb-0 start transaction on t.id = 1
begin;
select * from t where id = 1 for update;
TiDB 事务心跳超时机制测试_blog

tidb-0 periodically sends txn heartbeat to TiKV

TiDB 事务心跳超时机制测试_txn1_02

  1. Simulate network partition between tidb-0 and all tikv

TiDB 事务心跳超时机制测试_kind_03

TiDB 事务心跳超时机制测试_https_04
  1. During Simulation SessionB on tidb-1 select on t.id = 1
begin;
select * from t where id = 1 for update;
TiDB 事务心跳超时机制测试_kind_05

tidb-1 periodically sends txn heartbeat to TiKV

TiDB 事务心跳超时机制测试_blog_06

  1. Stop Simulation

tidb-0 can not continue sending heartbeat to TiKV

  1. SessionA on tidb-0 continue transaction and commit return KV error
update t set c = 'aa' where id = 1;
commit;
TiDB 事务心跳超时机制测试_tidb_07
  1. SessoinB on tidb-1 execute transaction successfully
update t set c = 'aa' where id = 1;
commit;
TiDB 事务心跳超时机制测试_tidb_08

场景2 事务心跳超时 & 锁不同 row id

  1. Session A on tidb-0 start transaction on t.id = 1
begin;
select * from t where id = 1 for update;
TiDB 事务心跳超时机制测试_kind_09

tidb-0 periodically sends heartbeat to TiKV

TiDB 事务心跳超时机制测试_kind_10

  1. Simulate network partition between tidb-0 and all tikv

TiDB 事务心跳超时机制测试_https_11

TiDB 事务心跳超时机制测试_kind_12
  1. During Simulation SessionB on tidb-1 select on t.id = 2
begin;
select * from t where id = 2 for update;
TiDB 事务心跳超时机制测试_blog_13

tidb-1 periodically sends heartbeat to TiKV

TiDB 事务心跳超时机制测试_blog_14

  1. Stop Simulation

tidb-0 can continue sending heartbeat to TiKV

TiDB 事务心跳超时机制测试_txn1_15

  1. SessionA on tidb-0 continues transaction successfully
update t set c = 'aa' where id = 1;
commit;
TiDB 事务心跳超时机制测试_blog_16
  1. SessoinB on tidb-1 continues transaction successfully
update t set c = 'bb' where id = 2;
commit;
TiDB 事务心跳超时机制测试_txn1_17

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK