wl21787
(lele217)
1
- 【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]
wl21787
(lele217)
3
您好,情况有所不同,我开启的是悲观事务,而案例中开启的是乐观事务。
重点是如何模拟出txnLock类型的事务冲突,而上面的案例中是无法实现的。
1、tidb 上面的监控是在悲观锁模式下出现的吗?
2、监控中 tikvlockfast 是指读写冲突,txnlock 是写写冲突
3、悲观锁的行为基本与 MySQL 一致,详情见下述链接:
https://pingcap.com/docs-cn/stable/reference/transactions/transaction-pessimistic/#悲观事务模式的行为
4、在开启悲观锁后,进行 DML 操作时,commit 前,会对目标 key 加锁,此时不会阻塞读。如果是遇到一个对该 key 的写请求,那么会处于等待状态,并且会进行内部更新 for update ts 进行重试操作。重试最多 256 次或者重试总时间超过了 innodb_lock_wait_timeout 设置,默认 50s。
另外,在 commit 进入提交阶段后,遵循的是乐观事务模型,此时仍可能会出现读写冲突,但是不会出现写写冲突。悲观锁在事务 commit 后释放。悲观锁相关的内容可以看下下面的链接:
wl21787
(lele217)
5
您好,测试情况以及监控显示都是在悲观模式下。
您所说的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; |