锁读写冲突

文档中出现这句话怎么理解?
读写冲突,当读数据时发现 key 有锁阻碍读,这个锁包括未提交的乐观锁和未提交的 prewrite 后的悲观锁。

tidb因为有mvcc机制,不应成存在读写冲突,当会话读取记录被另个会话锁定,该会话应该读取之前的版本,怎么会存在读写冲突呢?

2 个赞

以乐观锁举例。事务在读取时,需要读到目标 key 的 commit_ts 小于这个事务的 start_ts 的最新的数据版本。当读取时发现目标 key 上存在 lock 时,无法知道上锁的那个事务是在 Commit 阶段还是 Prewrite 阶段,所以就会出现读写冲突的。
https://docs.pingcap.com/zh/tidb/stable/troubleshoot-lock-conflicts#读写冲突

2 个赞

谢谢,那么发生读写冲突的时候,是发生等待呢,还是重试呢,悲观锁是什么情况呢?

1 个赞

乐观锁会进行 backoff 重试,悲观锁的事务之间出现会等锁的情况。

2 个赞

怎么能出现等待或者等待呢,我理解mvcc机制,应该查询上一个版本的数据才对呢

1 个赞

因为 TSO 的时间大于上一版本的,这时候就有新数据了,是等呢,还是不等
不等,就可能破坏了一致性,所以…

1 个赞

谢谢老师,能够提供一个场景,我模拟一下呢?

1 个赞

参考这个:

https://docs.pingcap.com/zh/tidb/stable/troubleshoot-lock-conflicts#事务被长时间阻塞

1 个赞

谢谢分享

1 个赞

乐观模式下,tidb提交时经历2个阶段, 1. prewrite,写kv和lock信息 2. commit: 写commit_ts,清理Primarykeylock(lock信息里包含事务的start_ts), 异步清理其他lock。 事务执行时会获取start_ts,然后找到所有已提交记录的commit_ts<start_ts值的最大commit_ts记录。当某个记录的锁信息还未被清理时,通过对比锁信息的start_ts(即lock_ts)发现小于后来读事务的start_ts,tidb无法判断该行记录是否已提交完成,然后进行backoff重试等待解锁,重试到一定次数后就报锁冲突。在GC时会有专门的阶段用于清理残留的锁信息。

悲观模式下,在DML阶段就会加上锁,读事务在遇到悲观锁后不需要进行解锁等待,直接返回已提交的最新数据。commit后按照乐观模式流程进行提交,在开启autocommit事务提交时是以乐观模式提交遇到锁冲突后再转换为悲观模式。

4 个赞

大佬总结的挺清晰~ 学习了

1 个赞

请问老师
重试到一定次数后就报锁冲突,报锁冲突后---->这个时候就会调用ResolveLocks 根据主锁的状态去提交还是回滚事务吧?

1 个赞

是的,primary key提交完成就提交,否则回滚

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