如何模拟不同的事务冲突类型

  • 【TiDB 版本】:V3.0.5,事务类型:pessimistic
  • 【问题描述】:如何模拟SQL实现监控中显示的问题:1)tikvlockfast 2)txnlock

测试场景:

表结构:
CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `c` int(11) DEFAULT NULL,
  `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2001

session A:
use tmp;
begin;
update t set c=100 where id=4;

session B:
use tmp;
begin;
update t set c=101 where id=4;
//block

此方法模拟出的冲突显示为:tikvlockfast

tidb.log内容:
[INFO] [adapter.go:493] ["pessimistic write conflict, retry statement"] [conn=34497] [txn=413923910122733569] [forUpdateTS=413923910122733569] [conflictCommitTS=0]

可以参照下这个帖子:

您好,情况有所不同,我开启的是悲观事务,而案例中开启的是乐观事务。

重点是如何模拟出txnLock类型的事务冲突,而上面的案例中是无法实现的。

1、tidb 上面的监控是在悲观锁模式下出现的吗?

2、监控中 tikvlockfast 是指读写冲突,txnlock 是写写冲突

3、悲观锁的行为基本与 MySQL 一致,详情见下述链接:

4、在开启悲观锁后,进行 DML 操作时,commit 前,会对目标 key 加锁,此时不会阻塞读。如果是遇到一个对该 key 的写请求,那么会处于等待状态,并且会进行内部更新 for update ts 进行重试操作。重试最多 256 次或者重试总时间超过了 innodb_lock_wait_timeout 设置,默认 50s。

另外,在 commit 进入提交阶段后,遵循的是乐观事务模型,此时仍可能会出现读写冲突,但是不会出现写写冲突。悲观锁在事务 commit 后释放。悲观锁相关的内容可以看下下面的链接:

您好,测试情况以及监控显示都是在悲观模式下。

您所说的tikvlockfast表示的是读写冲突,但是我在测试写写冲突的时候监控只会显示tikvlockfast,而不会显示txnlock。

还有您说的读写冲突如何模拟实现呢?txnlock也如何模拟实现呢?我在测试环境中模拟写写冲突,不会出现txnlock,只会出现tikvlockfast。

测试场景:

表结构:
CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `c` int(11) DEFAULT NULL,
  `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2001

session A:
use tmp;
begin;
update t set c=100 where id=4;

session B:
use tmp;
begin;
update t set c=101 where id=4;
//block

此方法模拟出的冲突显示为: tikvlockfast

模拟死锁: 死锁 监控中出现了txnlock

时间 事务A 事务B
t1 begin;
t2 update t set c=100 where id=1008;
t3 begin;
t4 update t set c=100 where id=5;
t5 update t set c=100 where id=5;//block
t6 锁自动释放 update t set c=100 where id=1008;ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
t7 update t set c=100 where id=1008;//block
t8 commit 锁释放
t9 commit;
  1. 上面关于悲观事务的读写,写写冲突在每个阶段的现象,请参照上面的来往帖子。

  2. 你那边是通过什么方式来确认各个实验现象对应的告警信息的?

  3. 模拟冲突的目的是什么?是要验证悲观和乐观共存时的原理和日志监控表现吗?