
全文约1418字,阅读约9分钟
B+树作为InnoDB存储引擎的存储结构,它的并发程度能够极大的影响着数据库的并发性能。本篇以MySQL 8.0为例,探究B+树并发控制中的一些原理。

B+树中的并发控制是为了解决并发读写中遇到的两个问题:
我们知道,在InnoDB中,有两种锁:
Lock,用来锁一些逻辑的对象(如表锁,行锁)以支持事务并发控制;
Latch,用来锁一些物理的数据结构(如Page)以实现数据结构的正确读写。在InnoDB 中latch又可以分为mutex和rwlock。

在InnoDB的实现中,B+树上的并发控制涉及到两种 latch:index latch 和 page latch。index latch是索引的锁,也就是B树级别的一把大锁;page latch是页面上的锁。
这里以InnoDB 8.0.18为例,分析B+树上的加锁规则。
在B+ Tree上共有三种基本操作:
读(BTR_SEARCH_LEAF ):分为点查询和范围查询;
乐观写(BTR_MODIFY_LEAF):仅影响到一个索引页的增删改;
悲观写(BTR_MODIFY_TREE):影响到超过一个索引页的增删改(如insert,delete操作导致了页的分裂或合并)。
获得索引的 S lock; 由上至下依次获取搜索路径节点的 S lock,直至叶子节点; 释放索引和中间节点的 S lock,仅保留叶子节点; 读叶子节点的内容; 释放叶子节点 S lock

获得索引的S lock; 由上至下 依次获取搜索路径节点的 S lock; 叶子节点获得 X lock; 释放索引和中间节点的 S lock,仅保留叶子节点; 修改叶子节点的内容; 释放叶子节点 X lock。

这个 latch mode 对应于一次会引起 SMO 的 操作。(SMO,split merge operation,即树的分裂或者合并操作)。在尝试修改一条记录时,会先进行乐观插入,如果乐观插入会引起B+树的结构变化,则重新进行一次悲观插入。
获得索引的 SX lock;
由上至下依次获取 可能引起分裂或合并的节点(如P1)的 X lock;
依次获得叶子节点左兄弟、自身、右兄弟的X lock;
修改索引结构和叶子节点的内容;
释放所有X lock。

相关的代码实现在btr_cur_search_to_nth_level函数中。
SMO 操作的过程中允许有read 和 乐观写入操作。sx lock和 s lock不冲突,提高了并发度;
SMO操作无法并行,sx lock和 sx lock是冲突的。
在后续篇幅中,将会跟大家分享B+树并发控制中的一些细节,以及一些其他B+树加锁方式,敬请期待!





