索引并发(蟹行协议和B-Link树)

索引并发

事务的并发问题可以通过两阶段封锁协议(2PL)或者多版本并发控制(mvcc)等方法解决。这些方法也同样适用于索引的并发访问控制。但是,由于索引访问频繁,它们将成为封锁竞争的集中点,导致低并发度。对事务而言,对一个索引查找两次,并在期间发现索引结构发生变化,这是完全可以接受的,只要索引查找返回正确的元组集。因此,只要维护索引的准确性,对索引进行非可串行化井发存取是可接受的。

蟹行协议

● 当搜索一条记录时,蟹行协议先用共享锁锁住根节点。然后尝试获取子节点的共享锁,获得子节点共享锁后,释放父节点上的锁,重复这个过程知道搜索到叶节点。
● 当插入或删除一条记录时:

1、采取与查找相同的方法,知道找到目标叶节点,到此为止,它只获得(或释放)共享锁。

2、用排它锁封锁该叶节点,插入或者删除记录。

3、如果需要分裂一个结点或将它与兄弟结点合并,或者在兄弟之间重新分配记录来平衡B+树,蟹行协议用排他锁封锁父结点。在完成这些操作后,它释放该结点和兄弟结点的锁。如果父结点需要分裂、合并或重新分布记录,协议保留父结点上的锁,以同样方式分裂、合并或重新分布记录,并且传播更远。否则,协议释放父结点的锁。

该协议的名字来源于螃蟹走路的方式:先移动一边的腿,然后移动另一条腿。如此交替进行,就像螃蟹移动一样。
向下的搜索操作和由于分裂、合并或重新分布记录而向上传播的封锁操作之间有可能出现死锁,系统能很容易地处理这种死锁,它先让搜索操作释放共享锁,然后从树根重启搜索。

B-Link树

为了避免在获取另一个节点的锁的时候还占有当前节点的锁(比如蟹行协议),可以对B+树进行改进,来获得更高的并发性。B-Link树要求每个结点(包括内部结点,不仅仅是叶结点)维护一个指向右兄弟结点的指针,这个指针是必要的,因为一个结点正在分裂时进行的查找可能不仅要查找该结点,而且可能要查找该结点的右兄弟结点(如果存在的话)。
B-Link树封锁协议过程:

查找。 B+树的每个结点在访问之前必须加共享锁,非叶子结点的锁应该在对其子节点申请共享锁前被释放(与蟹行协议不同)。如果结点分裂与查找同时发生,所希望的记录可能不再位于查找过程中所访问的某个节点内。在这种情况下,记录在由一个右兄弟结点表示的范围内,这是由系统循着指向右兄弟结点的指针而找到的。不过,系统封锁叶结点遵循两阶段封锁协议,以避免幻读。

插入与删除。 系统遵循查找规则,定位要进行插入或删除的叶结点。该结点的共享锁升级为排他锁,然后进行插入或删除。受插人或删除影响的叶结点封锁遵循两阶段封锁协议以避免幻读。

分裂。 如果事务使一个结点分裂,则创建新结点,并作为原始结点的右兄弟。没置原始结点与新产生结点的右兄弟指针。接着,事务释放原始节点的排它锁(假设它是一个内结点:叶结点以两阶段形式加锁),然后,发出对父结点加排他锁的请求,以便插入指向新结点的指针。(不必对新结点加锁或解锁。)

合并。 执行删除后,如果一个结点的记录太少,则必须对要与之合并的那个结点加排他锁。一旦这两个结点合并,则发出对父结点加排他锁的请求,以便删除要删除的结点,此时,事务释放合并结点的锁(与查找操作相反,封锁从下向上传播)。除非父结点也需再合并,不然释放其锁。

注意这样一个重要的事实:插人与删除操作可能封锁一个结点,释放该结点,然后对它重新封锁(分裂或合并节点需要加排它锁)。此外,与分裂或合并操作并发执行的查找可能发现要查找的记录被分裂或合并操作移到右兄弟结点(这并不影响查找操作,因为查找操作会查找当前节点的右兄弟节点)。

码值封锁(key value locking)与下一码值封锁(next key value locking)

我个人喜欢把key value翻译成记录,上文也是这么写的,下文引用《数据库系统概念》中的叫法,称之为码值。

一些索引并发控制机制不是以两阶段形式封锁索叶结点的,而是对个别的码值使用码值封锁,允许其他码值从同一个叶结点插入或删除。这样码值封锁增强了并发性,但是有可能引发幻读。为防止幻读,可以采用下一码封锁技术。这种技术中,每一个索引查找不仅封锁查找范围内的多个码(或单个码,在点查找时),而且封锁下一个码值,也就是刚好比范围内最后一个码值大的码值;并且,每一个插入必须不仅封锁要插入的值,而且包括下一个码值。这样,如果一个事务试图插入一个值到另一个事务的索引查找范围之内时,这两个事务将在插入码值的下一个码值上冲突。同样地,删除也必须封锁删除值的下一个码值,来保证它与别的查询的查找范围的并发冲突被检测到。
举例说明:
对于某个叶子节点A,内部含有如下码值
| 1 | 3 | 4 |
其中1和3之间可以插入2,这个位置被称作间隙。事务T1搜索小于等于2的码值,封锁了码值1和3。事务T2插入码值2,插入的时候要封锁下一个码值3,但是此时3已经被锁住了,所以写入操作挂起或取消,避免了事务T1幻读。

参考文献:

1.数据库系统概念(原书第5版) 第16章 并发控制

    原文作者:B树
    原文地址: https://blog.csdn.net/popvip44/article/details/57468202
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞