数据库
首页 > 数据库> > Mysql中的MVCC以及各种隔离级别

Mysql中的MVCC以及各种隔离级别

作者:互联网

总所周知,Mysql中有四种隔离级别:读未提交、读已提交、可重复读、序列化。这四种隔离级别的产生来自于对于数据读取过程中的一些错误的解决。错误主要分为这三类:脏读、可重复读、幻读。
这里对脏读、可重复读、幻读做一下简单地概述:
脏读:读到了未提交的数据,这一般是在读未提交隔离级别下会出现的问题。
不可重复读:同一条执行语句,第一次和第二次执行所得到的的解决不同,一般是发生在读已提交和读未提交隔离级别下
幻读:幻读主要指的是前后两次执行相同的语句,得到的结果的数量不同,读未提交、读已提交、可重复读都会出现幻读的问题。

对于出现脏读的情况,可以将隔离级别设置为读已提交,出现不可重复读可以将隔离级别设置为可重复读。这两种机制的隔离级别会利用到MVCC,我们分别来看一下MVCC是如何实现这两种隔离级别的。

这里需要介绍一下ReadView这个概念,事务会在启动的时候拍下快照,这个快照就是readview。读分为两种,分别是快照读和当前读,
快照读:简单的select操作(不包括 select ... lock in share mode, select ... for update)。  
当前读:当执行select...lock in share mode (共享读锁)、select...for update、update , delete , insert时,这时的快照是当前读。
MVCC只能在快照读下实现。
对于Readview,它由这几部分组成:

m_ids min_trx_id max_trx_id creator_trx_id
当前活跃事务编号 最小活跃事务编号 预分配事务编号,当前最大事务编号+1 ReadView创建者的事务编号

版本链的访问规则如下:
在读已提交和可重复读的下,版本连的访问规则如下:

图1

Snipaste_01png.png

图2

总结来说就是在访问数据的时候,查找版本连readview,如果被访问者的trx_id小于min_最小的活跃事务编号,那么该版本就能被当前事务访问,如果大于或等于最大事务编号就不能被访问,如果在最大值和最小值之间,那么不是活跃的就能被访问,活跃的不能被访问。

从上图1我们可以发现,在读未提交的情况下,仍然会出现不可重复读的现象,而MVCC解决不可重复读的方法是复用readView来实现。而在可重复读隔离界别加幻读仍然会发生,幻读的本质是是在两次快照读之间存在当前读,readview会重新生成,导致了幻读。而对于幻读的解决可以通过航所加间隙锁来实现。

标签:事务,隔离,访问,Mysql,trx,readview,版本,MVCC,id
来源: https://www.cnblogs.com/hello-liu/p/16380487.html