CockroachDB中的Latch和Lock

latch本质上也是一种锁,不过它相比于lock更加轻量级,更加灵活,容易获得和释放的锁,它在cockroachDB中的目的有三个:

 解决不同事务之间资源(表现为span)争抢的问题,保证串行化。

 解决事务操作原子性问题。保证同一个batch的写操作的原子性。

 解决事务流水线中异步提交的写操作日志复制确认。

latch不会造成阻塞,死锁,但是会造成等待。

latch只对存在资源争抢的span加锁,因此没有资源争抢的span之间不受latch的限制。

lock主要说的是事务的lock,它表现为txn record和write intent。两者都是用来表示事务层面的资源占用。

Latch和Lock都是为了解决资源争抢,不过Latch在数据库中lock有一定的区别,不同的数据库系统对两者的定位和使用略有差异,在CockroachDB中latch是一个低级别,轻量级和灵活的锁,本质上是为了解决不同的线程(一般意味着不同的事务)对同一个资源的访问(更多的是写权限的争抢)。在这个层面上latch是事务的底层依赖,即使没有事务,只要涉及到资源的争抢,就会用到latch来保护临界资源,它之所以轻量,我理解是因为它作用于发生潜在争抢的资源上,获取和释放都代价比较小,持有的时间也比较短。

     相比之下,lock是作用在事务上的,一般而言作用的范围和时间都比latch要大要长,lock在cockroachDB就是TXN write intent。

     如下表,是一个latch和lock的对比:


CockroachDB中的Latch和Lock_第1张图片

Cockroach DB的写操作处理都是先在lease holder上操作之后才提交raft复制给其他成员(lease holder应用raft log的时候会跳过自己已经在提交之前应用的提案),因此cockroachDB没有使用raft作为latch,而是自己开发了一个专门的latch manager。所有的写操作在操作之前首先申请latch,然后本地直接应用,成功后再复制给其他成员。

案例一

事务Txn 1 (A->2),同时事务Txn 2 (A->3),如果没有latch,那么这两个操作都可以成功(在rocksDB层面的写都是可以成功的),因此两个事务认为均可以提交成功,修改事务记录为commit,但是事务隔离已经被破坏。


案例二

   事务Txn1 的span是【A,C】,并且只包含两个记录A,C(cockroachDB会对离散的记录划定一个span以节约空间),事务Txn 2的span是【B,B】,只包含一个记录B,如果没有latch,我们做一个简单的场景,使用优化后的事务提交,即一阶段提交。那么这个时候一个读事务Txn 3 来读取A,B,C,就会出现两次读取获得的数据是不一致的。【如果存在latch,事务Txn 2就会在Txn1 之后排队,而不会出现并行写的问题】


参考资料:http://www.mamicode.com/info-detail-1509152.html

https://www.cnblogs.com/olinux/p/5174145.html

https://www.cnblogs.com/data-zhang/p/6971718.html

你可能感兴趣的:(CockroachDB中的Latch和Lock)