MVCC多版本控制: 指的是一种提高并发的技术。最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。在内部实现中,与Postgres在数据行上实现多版本不同,InnoDB是在undolog中实现的,通过undolog可以找回数据的历史版本。找回的数据历史版本可以提供给用户读(按照隔离级别的定义,有些读请求只能看到比较老的数据版本),也可以在回滚的时候覆盖数据页上的数据。在InnoDB内部中,会记录一个全局的活跃读写事务数组,其主要用来判断事务的可见性。
      MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC)。不仅仅是MySQL,包括Oracle,PostgreSQL等其他数据库系统也都实现了MVCC,但是各自的实现机制并不相同,因为MVCC并没有一个统一的标准。MVCC在很多情况下避免了加锁操作,因此开销更低。大多数的MVCC都实现了非阻塞的读操作,写操作也只锁定必要的行。
     MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据是一致的。根据事务开始的时间不同,每个事物对同一张表,同一时刻看到的数据可能是不一样的。不同存储引擎的MVCC实现是不同的,典型的有乐观(optimistic)并发控制和悲观(pessimistic)并发控制。

MVCC只在REPEATABLE READ和READ COMMITTED两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行,而SERIALIZABLE会对所有读取到的行都加锁。

MVCC的优缺点:

MVCC的目标是追求数据库处理高并发能力,实现了非阻塞的读操作。

但保存这两个额外的系统版本号,使大多数读操作都可以不用加锁,这样设计使得读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行,不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

 附:事务隔离级别

数据库事务具备ACID特性,即Atomicity(原子性) Consistency(一致性), Isolation(隔离性), Durability(持久性)

  原子性:要执行的事务是一个独立的操作单元,要么全部执行,要么全部不执行

  一致性:事务的一致性是指事务的执行不能破坏数据库的一致性,一致性也称为完整性。一个事务在执行后,数据库必须从一个一致性状态转变为另一个一致性状态。

  隔离性:多个事务并发执行时,一个事务的执行不应影响其他事务的执行,SQL92规范中对隔离性定义了不同的隔离级别:

读未提交(READ UNCOMMITED)->读已提交(READ COMMITTED)->可重复读(REPEATABLE READ)->序列化(SERIALIZABLE)。隔离级别依次增强,但是导致的问题是并发能力的减弱。

隔离级别

脏读

不可重复读

幻读

概念

READ UNCOMMITED

事务能够看到其他事务没有提交的修改,当另一个事务又回滚了修改后的情况,又被称为脏读dirty read

READ COMMITTED

×

事务能够看到其他事务提交后的修改,这时会出现一个事务内两次读取数据可能因为其他事务提交的修改导致不一致的情况,称为不可重复读

REPEATABLE READ

×

×

事务在两次读取时读取到的数据的状态是一致的

SERIALIZABLE

×

×

×

可重复读中可能出现第二次读读到第一次没有读到的数据,也就是被其他事务插入的数据,这种情况称为幻读phantom read, 该级别中不能出现幻读

大多数数据库系统的默认隔离级别都是READ COMMITTED(但MySQL不是),InnoDB存储引擎默认隔离级别REPEATABLE READ,通过多版本并发控制(MVCC,Multiversion Concurrency Control)解决了幻读、不可重复读的问题。

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

     注:1、不可重复读的和幻读区别,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

2、MVCC对于已提交读隔离级别下的事务在每次查询的开始都会生成一个独立的ReadView,而可重复读隔离级别则在第一次读的时候生成一个ReadView,之后的读都复用之前的ReadView。通过版本链,实现多版本,可并发读-写,写-读。通过ReadView生成策略的不同实现不同的隔离级别。

mysql MVCC原理理解的更多相关文章

  1. mysql mvcc 的理解

    mvcc 全称 multiple version concurrency control 多版本并发控制,是数据库领域比较常用的一种非锁并发技术. mysql 的innodb中,在RR.RC级别会使用 ...

  2. MySQL MVCC原理

    1 MVCC基本原理 MVCC:多版本并发控制(MVCC,Multiversion Currency Control).一般情况下,事务性储存引擎不是只使用表锁,行加锁的处理数据,而是结合了MVCC机 ...

  3. MySQL MVCC原理深入探索

    一.MVCC的由来 二.MVCC的实际应用 RR级别场景 RC级别场景 三.MVCC的实现 3.1 多版本的数据从哪里来--Undo Log 3.1.1 插入操作对应的undo log 3.1.2 删 ...

  4. Mysql 中的MVCC原理,undo日志的依赖

    一. MVCC 原理了解   原文点击:MVCC原理浅析 读锁: 也叫共享锁.S锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的 ...

  5. mysql事务原理及MVCC

    mysql事务原理及MVCC 事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个 基本特性如数家珍.但是聊起事务或者ACID的底层实现原理,往往言之不详,不 ...

  6. 轻松理解MYSQL MVCC 实现机制

    轻松理解MYSQL MVCC 实现机制 转载https://blog.csdn.net/whoamiyang/article/details/51901888 1. MVCC简介 1.1 什么是MVC ...

  7. Mysql高手系列 - 第22篇:深入理解mysql索引原理,连载中

    Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第22篇. 背景 使用mys ...

  8. java面试一日一题:讲对mysql的MVCC的理解

    问题:请讲下对mysql中MVCC的理解 分析:这个问题要回答的是对MVCC的理解,以及MVCC解决了什么问题这几个方面入手. 回答要点: 主要从以下几点去考虑, 1.什么是MVCC? 2.MVCC用 ...

  9. (转)MySQL备份原理详解

    MySQL备份原理详解 原文:http://www.cnblogs.com/cchust/p/5452557.html 备份是数据安全的最后一道防线,对于任何数据丢失的场景,备份虽然不一定能恢复百分之 ...

随机推荐

  1. 转 js实践篇:例外处理Try{}catch(e){}

    程序开发中,编程人员经常要面对的是如何编写代码来响应错误事件的发生,即例外处理(exception handlers).如果例外处理代码设计得周全,那么最终呈现给用户的就将是一个友好的界面.否则,就会 ...

  2. TFS修改了工作区

    计算机修改名字后,更换了TFS工作区,但原工作区的有些文件忘记签入: 解决方案: 删除原工作区即可,实现:到TFS工作区 - “管理工作区”,选中“显示远程工作区”,找到原工作区,删除即可.

  3. git初使用的心得

    转到Java方向后,版本控制工具也开始以git为主了.由于之前不怎么使用bash,所以目前还是以ui工具,比如sourcetree为主导,但一些简单的操作命令,已经能够快速地使用.sourcetree ...

  4. Centos 开机自动联网

    默认情况下,Centos不是自动连接上网的,要点击右上角有个电脑图标,选择system eth0进行连接, 可以修改开机启动配置只需修改:/etc/sysconfig/network-scripts/ ...

  5. Android RxJava2 浅析

    原文地址:http://blog.csdn.net/maplejaw_/article/details/52442065 Observable 在RxJava1.x中,最熟悉的莫过于Observabl ...

  6. js获取地址栏参数2种最简单方法

    NO1:(本人最喜欢) //普通参数 function GetQueryString(name) { var reg = new RegExp("(^|&)"+ name ...

  7. 用rownum先排序后分页

    今天突然想到rownum可以解决分页问题,于是做了各种实验,找个几个文章,最后有了一定成果. 现有表tablename,含有字段showorder,要求提取showorder的第11行到20行数据. ...

  8. SpringBoot项目的mybatis逆向工程

    <dependencies> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot& ...

  9. 梦想CAD控件com接口扩展数据

    随着CAD应用软件的飞速发展,经常需要保存一些与图形可视性无关的数据,即非图形参数.例如在绘制化验样图中包含品位数据.MxCAD定义了一类参数——实体扩展数据.扩展数据与实体的可视性无关,而是用户根据 ...

  10. 梦想CAD控件文字COM接口知识点

    一.参数绘制文字 在CAD设计时,需要绘制文字,用户可以设置设置绘制文字的高度等属性. 主要用到函数说明: _DMxDrawX::DrawText 绘制一个单行文字.详细说明如下: 参数 说明 DOU ...