悲观事务下,两条相同的update sql会相互响应导致耗时达到3秒以上吗

【 TiDB 使用环境】
订单数据
【概述】 场景 + 问题概述
两条相同的sql执行耗时达到3秒,sql语句如下:
update语句:UPDATE test SET up_order_id = “100”, order_id = “101”, response_code = 30, status = 1 WHERE hub_order_id = “300”;

表结构:up_order_id字段有唯一索引,order_id有索引,hub_order_id字段有唯一索引。
【背景】 做过哪些操作

【现象】 业务和数据库现象
业务层面触发了3秒超时的重试,重试了8次,最终该update sql执行了10次
【问题】 当前遇到的问题
耗时特别长,10条SQL的执行如下:
序号 开始时间 结束时间 耗时(S)
1 "16:10:51.338 " "16:11:20.998 " 29.6
2 "16:10:51.363 " "16:11:23.103 " 31.8
3 "16:10:54.521 " "16:11:23.604 " 29.1
4 "16:10:57.754 " "16:11:21.339 " 23.6
5 "16:11:00.957 " "16:11:23.017 " 22.1
6 "16:11:04.122 " "16:11:23.590 " 19.4
7 "16:11:07.355 " "16:11:22.741 " 15.4
8 "16:11:10.589 " "16:11:21.116 " 10.6
9 "16:11:13.733 " "16:11:22.377 " 8.6
10 "16:11:16.976 " "16:11:22.704 " 5.8

【业务影响】
超时
【TiDB 版本】
4.0

请问,从原理上讲,单条update执行很快,100ms以内,存在两条update sql执行会相互影响,导致耗时达到3秒吗?
悲观事务下,DML阶段已经加锁了,prewrite阶段为什么还会有锁冲突,那么DML阶段的锁又起了什么作用,避免了什么锁冲突呢?

1)如何开启悲观事务模式?
2)有没有使用autocommit? 如果使用了,则会优先用乐观事务模式。
3)悲观事务模式下,prewrite阶段就会判断是否有锁冲突。
判断方式:
(1) 在L列上是否有primarykey的锁记录,如果有,说明冲突;
(2)在本次事务开始时间之后 W 列上是否有更新 [startTs, +Inf) 的写操作已经提交,如果有,说明冲突;

另外可以可以根据tikv的日志和grafana监控辅助排查下 锁冲突的记录和指标数据。

1 个赞

是autocommit,如果是乐观事务模式的话,prewrite发生锁冲突的话,解决锁冲突耗时3秒也说不通,比如第一条先拿到锁,第二条会检测到冲突,但是不会把第一条打断吧,就是第一条的执行应该不受影响,第二条会慢一些吧

第二事务会backoff重试,但是重试有backoff time限制(随机,最小200ms,最大3000ms,总共backoff time时间总和是20s)和次数限制(由参数 pessimistic-txn.max-retry-count 控制),但是重试的时候 并没有排队,所以第二个事务可能执行成功的时间耗时很长。

嗯,第二个事务重试,耗时会比较长,第一个事务应该能很快执行结束吧,不应该被第二个事务打断重试吧,如果是这样的话,我遇到的场景,应该是其他的原因阻塞了第一个事务,导致耗时特别长

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。