B+树变体及其优化

文章探讨了B+树的悲观并发控制机制,介绍了crabbinglatch的实现方式,以及B-linktree如何通过引入sidepointer和highkey减少幻读并提高并发性能。B-wtree是一个正在进行中的项目。
摘要由CSDN通过智能技术生成

B+树数据结构这里不做赘述。

1. B+树的悲观并发控制可以采用crabbing latch。具体方法如下:

读操作:安全获取子节点页后加锁,释放父节点锁。

写操作:(在查找路径上,对覆盖了不安全节点的范围加锁;完成平衡操作后,自底向上解锁)

  1. 在修改路径上任一个被遍历到的内部节点,都保存到一个栈中,这是因为split之后的平衡操作是自底向上的。同时,对于访问到的内部节点如果是unsafe的,在push到栈中前要加写锁(unsafe说明有split或merge的风险,但由于我们是自上而下检测,而split是自底向上的,所以有可能出现假阳性)。
  2. 处理完父节点的调整后,释放子节点锁

螃蟹锁理论上不会发生死锁,且设计简单,一定程度减小了锁的粒度,但并不是真正意义上的“节点锁”,原因是在进行平衡操作时要将路径上所有unsafe节点都上锁,最差情况下(分裂到根)锁住整个路径。但由于其是自底向上解锁,自上而下解锁的顺序,不会发生死锁。

2. B-link tree

进一步减小并发力度,针对读写并发操作时无锁带来的问题(子节点split前后因父节点不一致导致reader读到旧视图而出现幻读),B-link tree微调了B+tree的结构,主要为两点

  • 内部节点若存在右兄弟,增加一个指向右兄弟的side pointer
  • 每个内部节点增加一个high key字段,表示其子树中最大的值。(等于最右侧子节点的high key,层层向上传递)

可以看到,在B-link的读写流程中,保存读写路径时无需对unsafe的节点提前加锁,而是能够真正意义上实现“节点”粒度的锁,同一时刻一个reader/writer只对一个(最多三个)节点上锁。再者,当出现上述读写冲突时,为了预防幻读,若发生上述情况,reader判断target 若大于旧节点high key,说明出现split,顺着side pointer遍历右兄弟节点查找即可。

另一个特点是,b-link tree的读操作是无锁的,写操作不会阻塞读,。

可见,引入high key和link指针,在并发查找时可以作为节点是否发生变更的根据。解决了树在修改过程中发生平衡操作时的查找定位问题

缺点:由于每个内部节点增加了两个字段,因此引入了额外的维护代价,尤其是每次split后,需要更新其high key,同时该high key需要更新到父节点的key。

3. B-w tree

(WIP)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值