一、概念
MVCC (Multiversion Concurrency Control),即多版本并发控制技术。它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,而是将行锁和行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。
1. MVCC解决了什么问题
- MVCC实现了MySQL中第三事务隔离级别,可重复读。
- 锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销。
2. MVCC的实现原理
MVCC是保存数据在某个时间点的快照实现的。不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制。、
Innodb MVCC主要是为Repeatable-Read事务隔离级别做的。在此隔离级别下,A、B客户端所示的数据相互隔离,互相更新不可见
3. MVCC的具体实现
以MySQL中InnoDB数据库引擎为例,讲述MVCC是怎样进行并发控制的。
- InnoDB的MVCC是通过在数据库表的后面加入两个隐藏列来实现的。分别保存了这个行的创建时间,一个保存的是行的删除时间。开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID.
- 具体的演示的例子可参考博客
https://blog.csdn.net/whoamiyang/article/details/51901888
4. MVCC在执行select、delete、 insert、 update的过程
SELECT
Innodb检查每行数据,确保他们符合两个标准:
- InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行
- 行的删除操作的版本一定是未定义的或者大于当前事务的版本号,确定了当前事务开始之前,行没有被删除。
符合了以上两点则返回查询结果。
INSERT
InnoDB为每个新增行记录当前系统版本号作为创建ID。
DELETE
InnoDB为每个删除行的记录当前系统版本号作为行的删除ID。
UPDATE
InnoDB复制了一行。这个新行的版本号使用了系统版本号。它也把系统版本号作为了删除行的版本。
二、MVCC的总结
一般我们认为MVCC有下面几个特点:
每行数据都存在一个版本,每次数据更新时都更新该版本
修改时Copy出当前版本随意修改,各个事务之间无干扰
保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback)
就是每行都有版本号,保存时根据版本号决定是否成功,听起来含有乐观锁的味道,而Innodb的实现方式是:
事务以排他锁的形式修改原始数据
把修改前的数据存放于undo log,通过回滚指针与主数据关联
修改成功(commit)啥都不做,失败则恢复undo log中的数据(rollback)
二者最本质的区别是,当修改数据时是否要排他锁定,
参考
https://blog.csdn.net/whoamiyang/article/details/51901888
https://www.cnblogs.com/chenpingzhao/p/5065316.html
https://blog.csdn.net/chen77716/article/details/6742128
可能的疑问
https://segmentfault.com/q/1010000002392124
更新时旧数据是否删除的答案
https://blog.csdn.net/phantomes/article/details/46425175
简短的总结
https://www.cnblogs.com/dongqingswt/p/3460440.html
网友评论