MVCC浅析
原文:---->>>>>> http://blog.csdn.net/chosen0ne/article/details/18093187

在并发读写数据库时,读操作可能会不一致的数据(脏读)。为了避免这种情况,需要实现数据库的并发访问控制,最简单的方式就是加锁访问。由于,加锁会将读写操作串行化,所以不会出现不一致的状态。但是,读操作会被写操作阻塞,大幅降低读性能。在Javaconcurrent包中,有copyonwrite系列的类,专门用于优化读远大于写的情况。而其优化的手段就是,在进行写操作时,将数据copy一份,不会影响原有数据,然后进行修改,修改完成后原子替换掉旧的数据,而读操作只会读取原有数据。通过这种方式实现写操作不会阻塞读操作,从而优化读效率。而写操作之间是要互斥的,并且每次写操作都会有一次copy,所以只适合读大于写的情况。

MVCC的原理与copyonwrite类似,全称是Multi-Version Concurrent Control,即多版本并发控制。在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读。MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。

实现原理:

------------------------------------------------------------------------------------------> 时间轴

|-------R(T1)-----|

|-----------U(T2)-----------|

如上图,假设有两个并发操作R(T1)和U(T2),T1和T2是事务ID,T1小于T2,系统中包含数据a = 1(T1),R和W的操作如下:

R:read a (T1)

U:a = 2    (T2)

R(读操作)的版本T1表示要读取数据的版本,而之后写操作才会更新版本,读操作不会。在时间轴上,R晚于U,而由于U在R开始之后提交,所以对于R是不可见的。所以,R只会读取T1版本的数据,即a = 1。

由于在update操作提交之前,不能影响已有数据的一致性,所以不会改变旧的数据,update操作会被拆分成insert + delete。需要标记删除旧的数据,insert新的数据。只有update提交之后,才会影响后续的读操作。而对于读操作而且,只能读到在其之前的所有的写操作,正在执行中的写操作对其是不可见的。

上面说了一堆的虚的理论,下面来点干活,看一下MySQL的innodb引擎是如何实现MVCC的。innodb会为每一行添加两个字段,分别表示该行创建的版本删除的版本,填入的是事务的版本号,这个版本号随着事务的创建不断递增。在repeated read的隔离级别(事务的隔离级别请看这篇文章)下,具体各种数据库操作的实现:

select:满足以下两个条件innodb会返回该行数据:(1)该行的创建版本号小于等于当前版本号,用于保证在select操作之前所有的操作已经执行落地。(2)该行的删除版本号大于当前版本或者为空。删除版本号大于当前版本意味着有一个并发事务将该行删除了。

insert:将新插入的行的创建版本号设置为当前系统的版本号。

delete:将要删除的行的删除版本号设置为当前系统的版本号。

update:不执行原地update,而是转换成insert + delete。将旧行的删除版本号设置为当前版本号,并将新行insert同时设置创建版本号为当前版本号。

其中,写操作(insert、delete和update)执行时,需要将系统版本号递增。

由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。

通过MVCC很好的实现了事务的隔离性,可以达到repeated read级别,要实现serializable还必须加锁。

mvcc摘抄的更多相关文章

  1. MySQL InnoDB下关于MVCC的一个问题的分析

      这个是网友++C++在群里问的一个关于MySQL的问题,本篇文章实验测试环境为MySQL 5.6.20,事务隔离级别为REPEATABLE-READ ,在演示问题前,我们先准备测试环境.准备一个测 ...

  2. 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)

    WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了 ...

  3. MySQL MVCC(多版本并发控制)

    概述 为了提高并发MySQL加入了多版本并发控制,它把旧版本记录保存在了共享表空间(undolog),当事务提交之后将重做日志写入磁盘(前提innodb_flush_log_at_trx_commit ...

  4. Distributed MVCC based cross-row transaction

    The algorithm for supporting distributed MVCC based cross-row transactions on top of a distributed k ...

  5. Hbase0.96 MVCC Lock 知识梳理

    HBASE0.96 MVCC 写入的时候 每个Region包含一个Memstore,维护一个MultiVersionConsistencyControl对象 w = mvcc.beginMemstor ...

  6. MVCC PostgreSQL实现事务和多版本并发控制的精华

    原创文章,同步发自作者个人博客,http://www.jasongj.com/sql/mvcc/ PostgreSQL针对ACID的实现机制 事务的实现原理可以解读为RDBMS采取何种技术确保事务的A ...

  7. bdb mvcc: buffer 何时可以被 看到; mvcc trans何时被移除

    # txn.h struct __db_txnregion SH_TAILQ_HEAD(__active) active_txn; SH_TAILQ_HEAD(__mvcc) mvcc_txn; # ...

  8. iOS——Core Animation 知识摘抄(一)

    本文是对http://www.cocoachina.com/ios/20150104/10814.html文章的关键段落的摘抄,有需要的看原文 CALayer和UIView的关系: CALayer类在 ...

  9. VGA信号一些分辨率的参数(摘抄)

    摘抄自:http://group.chinaaet.com/273/4100029440 VGA的接口时序如图所示,场同步信号VSYNC在每帧(即送一次全屏的图像)开始的时候产生一个固定宽度的高脉冲, ...

随机推荐

  1. java中 引用类型 和 基本类型 有何区别?

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newa ...

  2. Savelog项目总结回忆

    Savelog项目的细节已经不太记得,感觉有些遥远,需要翻回旧的笔记本电脑或者是旧的笔记本. 概述: 本项目采用的Linux C,监听一个或多个特殊的端口,当其中一个端口有发起连接时就产生一个新的线程 ...

  3. php完整验证码代码

    <?php require_once 'string.func.php'; //通过GD库做验证码 /** *添加验证文字 * @param int $type * @param int $le ...

  4. Python 关于正负无穷float(‘inf’)的一些用法

    Python中可以用如下方式表示正负无穷: float("inf"), float("-inf") 利用 inf 做简单加.乘算术运算仍会得到 inf > ...

  5. 百度富文本编辑器ueditor使用总结

    最近做的项目用到了ueditor这个东东,但是他的一些配置文档对初次使用者来说很难以理解,故作此总结 相关详细操作链接地址: http://blog.csdn.net/wusuopubupt/arti ...

  6. PI数据库的使用-PI System Management Tools

    1.PI连接管理器 2.标记搜索 3.当前值

  7. Data guard RAC配置【二】

    2. 利用duplicate配置容灾端 1.配置容灾端oracle用户的环境变量,这里以192.166.1.61为例. export ORACLE_BASE=/opt/oracle export OR ...

  8. BZOJ 3083 遥远的国度 树链剖分

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 797  Solved: 181[Submit][Status] Descrip ...

  9. JBoss for luna

    Redhat官方手顺 貌似已经404了,搬运地址 我的Eclipse是Luna,每次进入Eclipse Market去装 http://marketplace.eclipse.org/content/ ...

  10. Java语言基础(五) Java原始数据类型的分类以及数据范围

    Java原始数据类型的分类以及数据范围 1.基本数据类型分为:整型(byte, short, int, long),浮点型(float, double),字符型(char),布尔型(boolean) ...