我的理解:行锁是在索引叶子上锁,gap锁是前指针上锁,next-key lock是叶子和叶子的前指针上锁
next-key lock的“左开右闭”是指“扫描索引的过程中,先对叶子和前指针上锁(next-key lock),然后看情况将next-key lock退化”,而不是“扫描结束后,索引的锁是左开右闭的”
假设索引叶子是这样的: -∞,1,5,7,10,+∞
执行查询语句
where id >= 5 and id < 8
- 先扫描到叶子5,对叶子5和叶子5的前指针加锁,即next-key lock(1,5]。观察到叶子id是5,而语句是"id>=5",这个next-key lock可以做退化,取消叶子5前指针的锁,即叶子5的next-key lock退化成行锁[5]
- 扫描到叶子7,对叶子7和叶子7的前指针加锁,即next-key lock(5,7]。不需要退化。
- 扫描到叶子10,对叶子10和叶子10的前指针加锁,即next-key lock(7,10]。观察到叶子id是10,语句是"id<8",这个next-key lock可以做退化,取消叶子10的锁,即叶子10的next-key lock退化成gap锁(7,10)
结合上面三步,我们得到了的锁有[5],(5,7],(7,10),合起来是[5,10)的左闭右开区间。但我认为这里[5,10)和next-key lock的“左开右闭的特征”是两码事
题外:为什么next-key lock 使用前指针和行锁?而不是后指针和行锁?
我认为和索引叶子是递增排序有关。如果用后指针和行锁作为next-key lock(即左闭右开),那么在扫描时“先加next-key lock再退化”实现起来会比较别扭