基础储备----MVCC多版本并发控制

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

1. 前言

学习数据库事务的时候, 提到MVCC, 通过MVCC可以在无锁的情况下, 避免不可重复读, 这篇文章主要是介绍MVCC的原理.

2. MVCC简介

MVCC(Multiversion Concurrency Control),即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是,把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能.

3. 实现原理

MVCC可以提供基于某个时间点的快照,使得对于事务看来,总是可以提供与事务开始时刻相一致的数据,而不管这个事务执行的时间有多长.所以在不同的事务看来,同一时刻看到的相同行的数据可能是不一样的,即一个行可能有多个版本.是否听起来不可思议呢?
原来,为了实现MVCC, innodb对每一行都加上了两个隐含的列,其中一列存储行被更新的”时间”,另外一列存储行被删除的”时间”. 但是innodb存储的并不是绝对的时间,而是与时间对应的数据库系统的版本号,每当一个事务开始的时候,innodb都会给这个事务分配一个递增的版本号,所以版本号也可以被认为是事务号.对于每一个”查询”语句,innodb都会把这个查询语句的版本号同这个查询语句遇到的行的版本号进行对比,然后结合不同的事务隔离等级,来决定是否返回该行.
下面分别以select, delete, insert, update语句来说明:
1. SELECT
对于select语句, 只有同时满足了下面两个条件的行, 才能被返回:
a. 行的被修改版本号小于或者等于该事务号
b. 行的被删除版本号要么没有被定义,要么大于事务的版本号:行的删除版本号如果没有被定义,说明该行没有被删除过;如果删除版本号大于当前事务的事务号,说明该行是被该事务后面启动的事务删除的,由于是repeatable read隔离等级,后开始的事务对数据的影响不应该被先开始的事务看见,所以该行应该被返回.
2. INSERT
对新插入的行,行的更新版本被修改为该事务的事务号
3. DELETE
对于删除,innodb直接把该行的被删除版本号设置为当前的事务号,相当于标记为删除,而不是实际删除
4. UPDATE
在更新行的时候,innodb会把原来的行复制一份到回滚段中,并把当前的事务号作为该行的更新版本

4. MVCC的优缺点

上述策略的结果就是,在读取数据的时候,innodb几乎不用获得任何锁, 每个查询都通过版本检查,只获得自己需要的数据版本,从而大大提高了系统的并发度.
这种策略的缺点是,为了实现多版本,innodb必须对每行增加相应的字段来存储版本信息,同时需要维护每一行的版本信息,而且在检索行的时候,需要进行版本的比较,因而降低了查询的效率;innodb还必须定期清理不再需要的行版本,及时回收空间,这也增加了一些开销.

5. 参考链接

http://www.voidcn.com/article/p-vcstcmzj-beu.html

猜你喜欢

转载自blog.csdn.net/BraveLoser/article/details/82389085