MySQL InnoDB引擎 MVCC并发控制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tb3039450/article/details/66472579

首先,我们来介绍一下什么是MVCC,为什么要使用MVCC,MVCC的原理,然后结合MySQL的事务隔离级别来说一下MVCC的实现。


1.MVCC定义

MVCC全称Mutli Version Concurreny Control,多版本并发控制,也可称之为一致性非锁定读;它通过行的多版本控制方式来读取当前执行时间数据库中的行数据。实质上使用的是快照数据。


2.为什么要使用MVCC

  • 消除锁的开销;这个较好理解,如果要保证数据的一致性,最简单的方式就是对操作数据进行加锁,但是加锁不可避免的会有锁开销。所以,如果有能避免进行加锁的方式当然是最好的。
  • 提高并发度,这个我们先不在这说明,看完MVCC的原理以后你自然就明白了。

3.MVCC与事务隔离级别

在InnoDB事务隔离级别“读已提交”“可重复读”下 ,InnoDB存储引擎使用MVCC机制(非锁定一致性读)。在“读已提交”事务隔离级别下,对于快照数据,MVCC读总是读取被锁定行的最新的快照数据。而“可重复读”读到的总是读取事务开始时的行数据版本


4.MVCC原理

对于“可重复读”读到的总是读取事务开始时的行数据版本,那MVCC机制是如何保证可重复读的?其实就是在每一行记录的后面增加两个隐藏列,记录创建事务ID(创建版本号)和删除事务ID(删除版本号),在每次执行新的事务时,都会更新并且递增唯一的事务ID.

4.1 Insert事务

提交插入数据事务,此时创建事务ID为1.

id name create version delete version
1 a 1 undefined
2 b 1 undefined
3 c 1 undefined

4.2 Select事务

重点:select事务查询的记录需要同时满足以上两条规则:

  1. 查询行的事务创建/修改事务ID <= 当前执行事务ID(在当前事务之前被创建的行)
  2. 删除事务ID > 当前执行事务ID (已删除行不会被查到,在当前事务后删除的行会被查到)

此时执行事务ID=2的查询事务

id name
1 a
2 b
3 c

4.3 Delete事务

直接把该行的被删除事务ID设置为当前事务版本号,相当于标记删除,不是实际删除;例如删除id=1行

id name create version delete version
1 a 1 3
2 b 1 undefined
3 c 1 undefined

执行事务ID=4的查询事务,查询结果:

id name
2 b
3 c

4.4 Update事务

在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。 例如 更新id=2行的name=d

id name create version delete version
1 a 1 3
2 b 1 5
3 c 1 undefined
2 d 5 undefined

执行事务ID=6的查询事务,查询结果:

id name
3 c
2 d

5.为什么可重复读是我们经常使用到的事务隔离级别?

其实这个问题还是比较好理解的,在读已提交的事务隔离级别下,从形成事务的ACID特性来说,读已提交违反了事务ACID特性中的隔离性。
隔离性:每个事务的读写事务对象对其他事务的操作对象能相互分离。事务之间的操作是相对独立的,事务提交前对其他事务不可见


参考:

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页