ylldty
(Ti D Ber Q Yky5 Dvm)
1
TIKV 代码里面,Rollback 接口正常应该向 write cf 上面写回滚记录。这样即使网络问题,rollback 完成后,prewrite 由于网络原因被重复调用的时候,prewrite 会检测到回滚记录并且终止 prewrite 流程。
然而 Rollback 代码有一个特殊场景,并不会向 write cf 写入回滚记录,代码见:
所以实际上,什么也没有做,连 overlap 也没有设置,那么 prewrite 是如何识别到这种场景,并且阻止 prewrite 流程的呢?还是说什么机制可以保证 rollback 后肯定不会有网络原因导致 prewrite 又被调用?
找到很久之前的一段注释:
https://github.com/tikv/tikv/blob/c3f9fba14b04811e77614bcd50007bad17e251c3/src/storage/mvcc/txn.rs#L692
然后这个注释被一个 issue 打破了:
https://github.com/tikv/tikv/issues/7364
所以后续悲观事务的 primary 被保护起来了。。。
然而乐观事务就没有这个问题了吗?乐观锁是不需要检查 lock 的,为何也可以不被 protect 呢?
2 个赞
借楼咨询下,这个地方panic代表什么?我自己改代码,遇到了这里panic,没搞明白怎么产生的。
neilshen
(Neil Shen)
8
首先 CheckTxnStatus 一定会写入 protected rollback;然后如果你担心的是截图中的 ResolveLock 的处理里面没有设置 protected rollback 导致晚到的 prewrite 可能成功,理论上确实有可能,且乐观悲观都有可能,但是不影响事务正确性,因为在此之前 CheckTxnStatus 一定是写过 protected rollback 的(更严谨地说,对于普通 2PC 事务,primary 一定在 CheckTxnStatus 中被写入 protected rollback;对于 async commit 事务,则也有可能某个 secondary 在 CheckSecondaryLocks 期间写入 protected rollback),于是这个事务必定不可能进入 commit 状态,晚到的 prewrite 写入的锁最终总会在 resolve lock 中被清理
(注:上述回复来自我的同事)
2 个赞
ylldty
(Ti D Ber Q Yky5 Dvm)
9
多谢您解惑
这个流程涉及多个接口的交互,的确理解起来比较困难了。我后续可能会为这段代码添加足够的注释,让后面的 contributor 更容易的理解
ylldty
(Ti D Ber Q Yky5 Dvm)
10
从 CheckTxnStatus 的代码上面看,好像如果待检查的 primary lock 超时的话,写入的回滚记录并不是保护类型的呢?和您所说的逻辑有出入
1 个赞
redgame
(Ti D Ber Pa Amoi Ul)
11
乐观锁不检查锁的状态,可能不需要像悲观事务那样进行保护