在4.0中的执行计划带`for update `导致update拿不到锁引起大量3秒超时。

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【 TiDB 使用环境】
生产测试环境,V4.0.13

【概述】 少量update 语句出现3秒以上的延时,发现是prewrite:3.52过高,经查询由于update的执行计划不同导致,但是未查出具体哪里出的问题

【背景】
录制3.0TiDB中的语句实时写到4.0验证4.0集群发现的慢SQL

【现象】
通过流量复制验证4.0,有大量3秒超时的慢查询,报的错是被其他事务锁住了导致回退。但是在3.0的集群中未遇到这种情况。

SQL

UPDATE
  fcbox_pre_post_order
SET
  post_id = '123456',
  order_status = 300,
  update_emp = 'sys',
  update_sys_tm = '2021-07-21 15:50:39.449',
  charge_type = 1
WHERE
  post_id = '123456';

慢查询的执行计划

id                     	task     	estRows	operator info                                                                                                                                      	actRows	execution info                                                                                                                                                                                                                                                                                                                                                                   	memory 	disk
	Update_5               	root     	0      	N/A                                                                                                                                                	0      	time:3.15ms, loops:1, , commit_txn: {prewrite:3.52s, backoff: {time: 3.51s, type: [txnNotFound]}, resolve_lock: 3.52s, region_num:4, write_keys:5, write_byte:429, txn_retry:1}, lock_keys: {time:8.38ms, region:1, keys:1, lock_rpc:8.359945ms, rpc_count:1}                                                                                                                    	14.4 KB	N/A
	└─SelectLock_7         	root     	1.12   	for update                                                                                                                                         	0      	                                                                                                                                                                                                                                                                                                                                                                                 	N/A    	N/A
	  └─IndexLookUp_13     	root     	1.12   	                                                                                                                                                   	1      	time:2.94ms, loops:2, index_task: {total_time: 724µs, fetch_handle: 721.9µs, build: 653ns, wait: 1.48µs}, table_task: {total_time: 5.16ms, num: 1, concurrency: 4}                                                                                                                                                                                                            	22.4 KB	N/A
	    ├─IndexRangeScan_11	cop[tikv]	1.12   	table:fcbox_pre_post_order, index:idx_post_id(post_id), range:["123456","123456"], keep order:false	1      	time:2.21ms, loops:5, index_task: {total_time: 461µs, fetch_handle: 457.8µs, build: 1.09µs, wait: 2.12µs}, table_task: {total_time: 2.98ms, num: 1, concurrency: 4}, cop_task: {num: 1, max: 674.3µs, proc_keys: 1, tot_proc: 1ms, rpc_num: 1, rpc_time: 655.6µs, copr_cache: disabled}, tikv_task:{time:1ms, loops:1}, scan_detail: {total_process_keys: 1, total_keys: 2}	22.4 KB	N/A
	    └─TableRowIDScan_12	cop[tikv]	1.12   	table:fcbox_pre_post_order, keep order:false                                                                                                       	1      	time:1.93ms, loops:2, cop_task: {num: 1, max: 1.84ms, proc_keys: 1, rpc_num: 1, rpc_time: 1.82ms, copr_cache: disabled}, tikv_task:{time:0s, loops:1}, scan_detail: {total_process_keys: 1, total_keys: 1}                                                                                                                                                                       	N/A    	N/A

该SQL有两个执行计划,一个正常一个不正常。

正常的执行计划

	id                   	task     	estRows	operator info                                                                                                                                      	actRows	execution info                                                                                                                                                                                                               	memory 	disk
	Update_4             	root     	0      	N/A                                                                                                                                                	0      	time:1.55ms, loops:1, , commit_txn: {prewrite:1.28ms, get_commit_ts:137.2µs, commit:1.01ms, region_num:3, write_keys:3, write_byte:395}                                                                                     	14.4 KB	N/A
	└─IndexLookUp_11     	root     	1.12   	                                                                                                                                                   	1      	time:1.39ms, loops:2, index_task: {total_time: 663.1µs, fetch_handle: 660.5µs, build: 710ns, wait: 1.87µs}, table_task: {total_time: 3.44ms, num: 1, concurrency: 4}                                                      	22.4 KB	N/A
	  ├─IndexRangeScan_9 	cop[tikv]	1.12   	table:fcbox_pre_post_order, index:idx_post_id(post_id), range:["123456","123456"], keep order:false	1      	time:657.8µs, loops:3, cop_task: {num: 1, max: 626µs, proc_keys: 1, tot_proc: 1ms, rpc_num: 1, rpc_time: 613.9µs, copr_cache: disabled}, tikv_task:{time:0s, loops:1}, scan_detail: {total_process_keys: 1, total_keys: 2}	N/A    	N/A
	  └─TableRowIDScan_10	cop[tikv]	1.12   	table:fcbox_pre_post_order, keep order:false       

不正常的执行计划里面多了└─SelectLock_7 root 1.12 for update
在3.0都没遇到过这种语句。

【问题】 消除该执行计划不同

【TiDB 版本】
V4.0.13
【应用软件及版本】

【附件】 相关日志及配置信息

  • TiUP Cluster Display 信息
  • TiUP CLuster Edit config 信息

监控(https://metricstool.pingcap.com/)

  • TiDB-Overview Grafana监控
  • TiDB Grafana 监控
  • TiKV Grafana 监控
  • PD Grafana 监控
  • 对应模块日志(包含问题前后 1 小时日志)
1赞

你现在用的环境,是乐观事务,还是悲观事务?
select * from xxx for update 是带有锁性质的请求,你希望锁住,还是不锁住?

3.0 默认是乐观事务,不支持悲观模式
4.0 支持乐观和悲观两种事务模型,你想切换到3.0 的模式么? 改下配置就好了

3.0使用的是悲观锁

4.0也是

目前是update语句执行计划中出现了 for update的操作,目前正在翻代码看下啥情况,这个执行计划在3.0是没有出现过的。而且文档也没介绍过

收到,这个可能需要CTC 的小伙伴来支持了

3.0.8 以后的版本是支持悲观锁的

tidb-server 的一个参数: txn-local-latches ,看看 v3 和 v4 配置有没有不同?(2个版本都是 默认关闭)

该参数都没调整过,v4当中查询tidb_config参数和CLUSTER_CONFIG表中都未发现该配置,v3中显示enabled = false

1、先回答问题本身哈,这个时间长,是锁冲突导致,解决问题,建议还是程序去避免这个情况
2、v4和 v3 表现不一致,我建议查看一下 % tidb_retry_limit% 重试参数,看看2个版本是否一致



要不然把需要的信息都列一下,一起看下。

现在的问题是3.0会一点问题都没,4.0有问题。这个跟程序也没直接关系吧。大概率是设置上面有问题。

1、能介绍下遇到txnNotFound根本原因是啥么。
2、有少量的执行计划会出现└─SelectLock_7 root 1.12 for update。这块有介绍么。

1、txnnotfound 直接官网搜就ok,SelectLock 没有相关介绍
2、你的语句正常执行时间没差多少(v4 时间超过3s 是因为锁冲突导致 backoff,锁冲突本身代表程序逻辑可以优化,这个也是彻底解决问题的办法)
3、至于 v3 和 v4 执行计划不一样的问题,是不是导致锁冲突,这个有待验证(我上面验证几个参数,是确认tidb测锁相关的事情),你的 SQL 前后v3 和 v4 写的 key 及 涉及的region 数量是不同的,所以建议,你不要通过 对比来解决,按照正常的问题排查问题就好了(tidb-server 日志,确定锁冲突的原因是 表 还是索引,找到原因后,建议让程序就修改)