以下为个人理解,如有错误,还望指正!!

mysql的大多数事务型存储引擎实现的都不是简单的行级锁,基于提升并发性能的考虑,他们一般都同时实现了多版本并发控制,可以认为MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低,虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。

MVCC的实现是通过保存数据在某个时间点的快照来实现的,也就是说,不管需要执行多长时间,只要事务开始时间相同,每个事务看到的数据都是一致的,事务开始的时间不同时,每个事务对同一张表,同一时刻看到的数据可能是不一样的(因为不同的时间点可能数据就已经产生了不同的快照版本,而每个事务在默认的RR隔离级别下只能看到事务开始时的数据快照)。说道不同的存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制,下面简单说明MVCC是如何工作的:

innodb的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间),当然,存储的并不是实际的时间值,而是系统版本号(system version number),每开始一个新的事务,系统版本号都会自动递增,事务开始时刻的系统版本号作为事务的版本号,用来和查询到的每行记录的版本号进行比较,下面看repeatable read隔离级别下,MVCC具体是如何操作的:

select:

innodb会根据以下两个条件检查每行的记录

A:innodb只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始之前已经存在,要么是事务自身插入或修改的数据。

B:行的删除版本要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除(即,这样做的目的是为了事务不会读取到被真正删除的行,删除版本号小于当前事务版本号的表示操作删除记录的事务已经提交--数据已经被删除,删除版本号大于当前事务版本号的表示这个事务是在当前事务之后开始的--当前事务开始时这些记录是还存在的,根据事务的隔离性,一致性要求,之后开始的事务操作的记录并提交,对当前事务不可见,所以还需要当前事务能够查询这些记录--只能够查询,不能够修改和删除)。

只有满足以上两个条件的才可以返回作为查询结果。

insert:

innodb为新插入的每一行保存当前系统版本号作为行版本号

delete:

innodb为删除的每一行保存当前系统版本号作为行删除标识

update:

innodb为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识

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

MVCC只在repeatable-read和read-committed两个隔离级别下才工作,其他两个隔离级别都和MVCC不兼容,因为read uncommitted总是读取最新的数据行,而不是符合当前事务版本的数据行,而serializeble则会对所有读取的行都加锁。

另外要注意:MVCC在RR和RC隔离级别下的区别,在RR隔离级别下,一个事务只能读取到事务开始的那个时刻的数据快照,即,别的事务修改并提交的数据在自身没有提交之前一般读取不到(加for update语句的select除外,因为这个语句要对数据加X锁必须读取最新的数据快照),在RC隔离级别下,事务总是读取数据行的最新快照,即会产生不可重复读的问题。

浅谈mysql mvcc的更多相关文章

  1. 浅谈mysql主从复制的高可用解决方案

    1.熟悉几个组件(部分摘自网络)1.1.drbd     —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...

  2. 浅谈mysql innodb缓存策略

    浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb buffe ...

  3. 浅谈mysql配置优化和sql语句优化【转】

    做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...

  4. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  5. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景   Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...

  6. 浅谈MySQL存储引擎-InnoDB&MyISAM

    存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式是不同的.每一种存储引擎都有它的优势和劣势,本文只讨论最常见 ...

  7. 重新学习MySQL数据库6:浅谈MySQL的中事务与锁

    『浅入深出』MySQL 中事务的实现 在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的:在这篇 ...

  8. (转)运维角度浅谈MySQL数据库优化

    转自:http://lizhenliang.blog.51cto.com/7876557/1657465 一个成熟的数据库架构并不是一开始设计就具备高可用.高伸缩等特性的,它是随着用户量的增加,基础架 ...

  9. 运维角度浅谈MySQL数据库优化(转)

    一个成熟的数据库架构并不是一开始设计就具备高可用.高伸缩等特性的,它是随着用户量的增加,基础架构才逐渐完善.这篇博文主要谈MySQL数据库发展周期中所面临的问题及优化方案,暂且抛开前端应用不说,大致分 ...

随机推荐

  1. random模块使用

    import random #print random.random() #0.522622274753 #print random.randint(,) 生成1-5之间的一个随机整数 #print ...

  2. PHP框架Yii2.0安装(基础版、高级版)

    最近农成也是切入了yiiframework 2.0,就是安装yii2.0就花费了不少的时间,为此做了很多的弯路,特此写一篇博文来给后面学习的同学少走一点的弯路.写的不好的地方欢迎各位学习的同学们能够指 ...

  3. https协议

  4. ActionController::InvalidAuthenticityToken 解决办法(第二种尤其有效)

    第一种:  Ror代码 class FooController < ApplicationController       protect_from_forgery :except => ...

  5. Java基础(50):二分法查找的非递归实现和递归实现(完整代码可运行,参考VisualGO理解更佳)

    一.概念 二分查找算法也称折半查找,是一种在有序数组中查找某一特定元素的搜索算法. 二.算法思想 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束:如果某一特定元素大于或者 ...

  6. oracle 新手遇到常见问题的解决办法

    可能照成以下问题的原因也许有很多种,但是就小白而言,我只记录自己学习过程中遇到的所有的问题.希望对一些新手 小白们有所帮助. 原因是 sys 不是sysdba 用户,你要将其作为sysdba 用户登录 ...

  7. list和set的区别

    list和set的区别 相同点:list,set都是继承自collection接口 不同点: a.list-->元素有放入顺序,元素可重复  set-->元素无放入顺序,元素不可重复 b. ...

  8. 机器学习(Machine Learning)&深入学习(Deep Learning)资料

    <Brief History of Machine Learning> 介绍:这是一篇介绍机器学习历史的文章,介绍很全面,从感知机.神经网络.决策树.SVM.Adaboost 到随机森林. ...

  9. php防止表单重复提交

    解决方案一:引入cookie机制来解决 提交页面代码如下a.php代码如下: <form id="form1" name="form1" method=& ...

  10. Java throw:异常的抛出怎么回事

    到目前为止,你只是获取了被Java运行时系统抛出的异常.然而,程序可以用throw语句抛出明确的异常.Throw语句的通常形式如下:    throw ThrowableInstance;这里,Thr ...