我的理解:
有些框架为了实现乐观锁,在生成的表结构上创建一个时间字段或者版本号字段,commit的时候会比较读到的内容有无变化,如果时间大于本事务之前读到的值,就说明已经有其它的事务更新过。
tidb实现乐观锁也类似的方法,在prewrite阶段,去比较是否有其它的事务更新过
虽然我不知道问题如何定位,不过发生冲突的并不是悲观事务。
用mok 解析日志中出现的几个key,结果如下:
key:
lock:
lock.secondaries:
可以看到key和lock的冲突,是在同一个索引值上。lock上写入的这个索引值,还需要同步一个表里面的值。
for_update_ts: TimeStamp(0)
只有乐观事务for_update_ts=0。
在tidb中,自动提交的事务默认是使用乐观事务的。
https://docs.pingcap.com/zh/tidb/stable/tidb-configuration-file#pessimistic-auto-commit
所以这应该是2个自动提交的乐观事务,在写入同一个索引值的时候发生的冲突,导致async commit超时,事务退回2pc。然后时间变的更长了。
我这边已经修改过这个值pessimistic-auto-commit,但是还是有insert into在prewrite消耗时间长,我怀疑是连接没有断开,还是用的是之前的会话值
我仔细看了下我自己的库偶尔也会有类似问题。
对着grafana看了下。在TiKV-Trouble-Shooting 下有个Pending compaction bytes图。
可以看到这类prewrite升高的时候基本伴随着某一个tikv的Pending compaction bytes升高。
同时也能看到磁盘在这个时候的大量写入。
我这边的这类问题应该是compaction 引起的写放大造成的。
各位的情况是否如此,可以自己对照看一下,如何改善,我还得再看看配置了。
v3以后默认悲观锁
从最基本的检查,从监控上看变慢时候的cpu 内存 硬盘使用率
学习了
感谢提醒。经过确认,我们的业务系统确实使用了自动提交策略(也就是说确实是默认使用了乐观事务),在 TiDB 日志中也的确发现存在大量的事务重试日志。
但进一步排查发现,出现重试的语句,与业务反馈的 INSERT 慢语句所涉及的表,并不是同一批表。
目前这个问题仍然未明确。但我觉得你这个回答是最具有明确且具体的提示排查方向作用,感谢提醒。
1、观察下TIKV DURATION 是某个TIKV响应慢 还是好多个
2、根据TIKV duration 可以看看日志,有可能是COMPACTION引起的,
3、tidb duration 响应是不是也比较高,资源够不?
##通过以上基本能够定位
4、不行就升级吧
自动提交我觉得跟锁应该没多大关系把
此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。