1、MVCC简介

1.1 MVCC是什么?

MVCC,Multi-Version Concurrency Control,多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;

1.2 MVCC是为了解决什么?

  • 大多数的MYSQL事务型存储引擎,如,InnoDB,Falcon以及PBXT都不使用一种简单的行锁机制.事实上,他们都和MVCC–多版本并发控制来一起使用
  • 大家都应该知道,锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销

  众所周知,在MYSQL中,MyISAM使用的是表锁,InnoDB使用的是行锁。而InnoDB的事务分为四个隔离级别,其中默认的隔离级别REPEATABLE READ需要两个不同的事务相互之间不能影响,而且还能支持并发,这点悲观锁是达不到的,所以REPEATABLE READ采用的就是乐观锁,而乐观锁的实现采用的就是MVCC。正是因为有了MVCC,才造就了InnoDB强大的事务处理能力。

MVCC解决的问题是读写互相不阻塞的问题,每次更新都产生一个新的版本,读的话可以读历史版本。试想,如果一个数据只有一个版本,那么多个事务对这个数据进行读写是不是需要读写锁来保护?
一个读写事务在运行的过程中在访问数据之前先加读/写锁这种实现叫做悲观锁,悲观体现在,先加锁,独占数据,防止别人加锁。
乐观锁呢,读写事务,在真正的提交之前,不加读/写锁,而是先看一下数据的版本/时间戳,等到真正提交的时候再看一下版本/时间戳,如果两次相同,说明别人期间没有对数据进行过修改,那么就可以放心提交。
乐观体现在,访问数据时不提前加锁。在资源冲突不激烈的场合,用乐观锁性能较好。如果资源冲突严重,乐观锁的实现会导致事务提交的时候经常看到别人在他之前已经修改了数据,然后要进行回滚或者重试,还不如一上来就加锁。

所以通常我们把没有开启MVCC特性的,使用原来的锁机制来保证数据一致性的这种锁叫悲观锁,
而对开启MVCC机制的锁,叫做乐观锁。

1.3 MVCC实现

  MVCC是通过保存数据在某个时间点的快照来实现的. 不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制.

2、MVCC具体实现

下面,我们通过InnoDB的MVCC实现来分析MVCC使怎样进行并发控制的.
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,分别保存了这个行的创建时间,一个保存的是行的删除时间。这里存储的并不是实际的时间值,而是系统版本号(可以理解为事务的ID),没开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID.下面看一下在REPEATABLE READ隔离级别下,MVCC具体是如何操作的.

2.1简单的小例子

create table yang(
id int primary key auto_increment,
name varchar(20));

假设系统的版本号从1开始.

INSERT

InnoDB为新插入的每一行保存当前系统版本号作为版本号.
第一个事务ID为1;

start transaction;
insert into yang values(NULL,'yang') ;
insert into yang values(NULL,'long');
insert into yang values(NULL,'fei');
commit;

对应在数据中的表如下(后面两列是隐藏列,我们通过查询语句并看不到)

id name 创建时间(事务ID) 删除时间(事务ID)
1 yang 1 undefined
2 long 1 undefined
3 fei 1 undefined

SELECT

InnoDB会根据以下两个条件检查每行记录:
a.InnoDB只会查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的.
b.行的删除版本要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除.
只有a,b同时满足的记录,才能返回作为查询结果.

DELETE

InnoDB会为删除的每一行保存当前系统的版本号(事务的ID)作为删除标识.
看下面的具体例子分析:
第二个事务,ID为2;

start transaction;
select * from yang; //(1)
select * from yang; //(2)
commit;

假设1

假设在执行这个事务ID为2的过程中,刚执行到(1),这时,有另一个事务ID为3往这个表里插入了一条数据;
第三个事务ID为3;

start transaction;
insert into yang values(NULL,'tian');
commit;

这时表中的数据如下:

id name 创建时间(事务ID) 删除时间(事务ID)
1 yang 1 undefined
2 long 1 undefined
3 fei 1 undefined
4 tian 3 undefined

然后接着执行事务2中的(2),由于id=4的数据的创建时间(事务ID为3),执行当前事务的ID为2,而InnoDB只会查找事务ID小于等于当前事务ID的数据行,所以id=4的数据行并不会在执行事务2中的(2)被检索出来,在事务2中的两条select 语句检索出来的数据都只会下表:

id name 创建时间(事务ID) 删除时间(事务ID)
1 yang 1 undefined
2 long 1 undefined
3 fei 1 undefined

假设2

假设在执行这个事务ID为2的过程中,刚执行到(1),假设事务执行完事务3后,接着又执行了事务4;
第四个事务:

start   transaction;
delete from yang where id=1;
commit;

此时数据库中的表如下:

id name 创建时间(事务ID) 删除时间(事务ID)
1 yang 1 4
2 long 1 undefined
3 fei 1 undefined
4 tian 3 undefined

接着执行事务ID为2的事务(2),根据SELECT 检索条件可以知道,它会检索创建时间(创建事务的ID)小于当前事务ID的行和删除时间(删除事务的ID)大于当前事务的行,而id=4的行上面已经说过,而id=1的行由于删除时间(删除事务的ID)大于当前事务的ID,所以事务2的(2)select * from yang也会把id=1的数据检索出来.所以,事务2中的两条select 语句检索出来的数据都如下:

id name 创建时间(事务ID) 删除时间(事务ID)
1 yang 1 4
2 long 1 undefined
3 fei 1 undefined

UPDATE

InnoDB执行UPDATE,实际上是新插入了一行记录,并保存其创建时间为当前事务的ID,同时保存当前事务ID到要UPDATE的行的删除时间.

假设3

假设在执行完事务2的(1)后又执行,其它用户执行了事务3,4,这时,又有一个用户对这张表执行了UPDATE操作:
第5个事务:

start  transaction;
update yang set name='Long' where id=2;
commit;

根据update的更新原则:会生成新的一行,并在原来要修改的列的删除时间列上添加本事务ID,得到表如下:

id name 创建时间(事务ID) 删除时间(事务ID)
1 yang 1 4
2 long 1 5
3 fei 1 undefined
4 tian 3 undefined
2 Long 5 undefined

继续执行事务2的(2),根据select 语句的检索条件,得到下表:

id name 创建时间(事务ID) 删除时间(事务ID)
1 yang 1 4
2 long 1 5
3 fei 1 undefined

还是和事务2中(1)select 得到相同的结果.

MySQL的MVCC机制的更多相关文章

  1. MySQL的事务机制和锁(InnoDB引擎、MVCC多版本并发控制技术)

    一.事务(数据库的事务都通用的定义) 1.1 事务定义 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行.事务通常以 BEGIN TRANSACTION 开始 ...

  2. 一文读懂MySQL的事务隔离级别及MVCC机制

    回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...

  3. MySQL多版本并发控制——MVCC机制分析

    MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写.写读操作并发执行,提 ...

  4. mysql的MVCC多版本并发控制机制

    MVCC多版本并发控制机制 全英文名:Multi-Version Concurrency Control MVCC不会通过加锁互斥来保证隔离性,避免频繁的加锁互斥. 而在串行化隔离级别为了保证较高的隔 ...

  5. MySQL 学习笔记(二)MVCC 机制

    之前在讲 MySQL 事务隔离性提到过,对于写操作给读操作的影响这种情形下发生的脏读.不可重复读.虚读问题.是通过MVCC 机制来进行解决的,那么MVCC到底是如何实现的,其内部原理是怎样的呢?我们要 ...

  6. mysql中innodb引擎的mvcc机制和BufferPool缓存机制

    一.MVCC (1)mvcc主要undo日志版本链和read-view一致性视图来保证多事务的并发控制,mvcc是innodb的一种特殊机制,他保证了事务四大特性之一的隔离性(原子性,一致性,隔离性) ...

  7. mysql的并发处理机制_下篇

        MySQL的并发处理机制,有MVCC及锁机制来处理,上篇简要说明了 MVCC及隔离级别,这篇来说说mysql下的锁.     温馨提示:下文有几个表格长度较长,右下角的博文导航目录会挡道,浏览 ...

  8. MySQL InnoDB MVCC深度分析

    关于MySQL的InnoDB的MVCC原理,很多朋友都能说个大概: 每行记录都含有两个隐藏列,分别是记录的创建时间与删除时间 每次开启事务都会产生一个全局自增ID 在RR隔离级别下 INSERT -& ...

  9. MySQL InnoDB MVCC

    MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...

随机推荐

  1. Docker: Error response from daemon: Get.........unauthorized: incorrect username or password

    今天在Centos中使用docker拉取redis镜像时报Error response from daemon: Get https://registry-1.docker.io/v2/library ...

  2. Python3爬虫使用requests爬取lol英雄皮肤

    本人博客:https://xiaoxiablogs.top 此次爬取lol英雄皮肤一共有两个版本,分别是多线程版本和非多线程版本. 多线程版本 # !/usr/bin/env python # -*- ...

  3. vue相关坑

    1:vue 动态加载图片路径报错解决方法,循环遍历图片不显示图片 解决方法:https://www.cnblogs.com/qingcui277/p/8930507.html

  4. mysql的锁与事务

    1. MySQL中的事物 1.InnoDB事务原理 1. 事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态. 2. 在数据库提交 ...

  5. 17 Spring Data JPA的常用接口分析

    思考 在客户的案例中,我们发现在自定义的CustomerDao中,并没有提供任何方法就可以使用其中的很多方法,那么这些方法究竟是怎么来的呢?答案很简单,对于我们自定义的Dao接口,由于继承了JpaRe ...

  6. Idea安装教程以及环境变量配置

    IDEA安装以及JDK环境变量 环境变量配置 下载jdk

  7. JAVA生成EXCEL模板

    JAVA生成excel模板,支持1.必填字段前加 红色 * 2.定义可选值下拉列表 valList3.定义名称并通过名称设置可选值 refName(名称在sheet2,sheet2自动隐藏)4.支持设 ...

  8. Wireshark过滤器写法总结

    目录 #Wireshark提供了两种过滤器: 1.捕获过滤器 2.显示过滤器 #过滤器具体写法 #显示过滤器写法 #捕捉过滤器写法 #Wireshark提供了两种过滤器: 1.捕获过滤器 捕获过滤器: ...

  9. winform不能循环引用,使用接口传值到界面

    public partial class frmMain : Form, IFormManager { 4 public frmMain() { InitializeComponent(); 8 } ...

  10. 搭建XSS测试平台

    XSS测试平台是测试XSS漏洞获取cookie并接收web页面的平台,XSS可以做js能做的所有事情,包括但不限于窃取cookie,后台增删文章.钓鱼.利用xss漏洞进行传播.修改网页代码.网站重定向 ...