本文探讨innodb如何使用mvcc和各种锁机制,保障mysql的四层隔离等级的。
为了保证并发事务的正常执行,innodb使用了各种锁,总结如下图0.1.1和图0.1.2。比如,在解决幻读问题时,用到了gap lock。读者最好查阅其它文章,对下面的锁的行为、作用有所理解。尤其应当理解record lock、gap lock、next-key lock和X lock、S lock。 至于IX lock(意向排他锁)和IS lock(意向共享锁), 暂时不是讨论重点。
图0.1.1 innodb的锁 表格分类
图0.1.2 innodb的锁 树形分类
有四大并发问题,更新丢失(第一类和第二类)、脏读、不可重复读、幻读。你需要事先了解这四个问题是怎样的。
为了解决这些并发问题,mysql提出了事务的四大隔离等级:RU、RC、RR、SR。你需要事先了解四个隔离等级所解决的并发问题。我总结了如下:
图0.3.1
我们研究这些方法,都是为了理解并发问题是如何被解决的。不管是锁也好,隔离等级也好,都是为了解决那些并发问题。
关于这些方案的总结见图1.1。
图1.1 并发问题的解决方案
为了解决并发问题,有人提出了三种封锁协议,级别越高,解决的并发问题越多。 图2.1描述了三种封锁协议的做法,和它们解决的并发问题。图中的三种封锁协议,显然都是基于对数据加X锁和S锁实现的[2]。
图2.1 封锁协议解决并发问题
加锁的办法固然有效,但在读多写少的实际场景中,每次读取都加锁的做法太影响效率。
针对解决脏读、不可重复读问题时加读锁会影响效率的问题,innodb提出了mvcc。为了解决幻读问题,还另外使用了record lock、gap lock等锁。各个隔离等级用到的技术如图3.1:
图3.1 各个隔离等级用到的技术