关于 MVCC 的基础
作为第一篇对 MVCC 的学习材料,以下内容翻译自 Wikipedia。
1. 什么是MVCC
1.1 基础概念
MVCC,Multi-Version Concurrency Control,多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。
如果有人从数据库中读数据的同时,有另外的人写入数据,有可能读数据的人会看到『半写』或者不一致的数据。有很多种方法来解决这个问题,叫做并发控制方法。最简单的方法,通过加锁,让所有的读者等待写者工作完成,但是这样效率会很差。MVCC 使用了一种不同的手段,每个连接到数据库的读者,在某个瞬间看到的是数据库的一个快照,写者写操作造成的变化在写操作完成之前(或者数据库事务提交之前)对于其他的读者来说是不可见的。
当一个 MVCC 数据库需要更一个一条数据记录的时候,它不会直接用新数据覆盖旧数据,而是将旧数据标记为过时(obsolete)并在别处增加新版本的数据。这样就会有存储多个版本的数据,但是只有一个是最新的。这种方式允许读者读取在他读之前已经存在的数据,即使这些在读的过程中半路被别人修改、删除了,也对先前正在读的用户没有影响。这种多版本的方式避免了填充删除操作在内存和磁盘存储结构造成的空洞的开销,但是需要系统周期性整理(sweep through)以真实删除老的、过时的数据。对于面向文档的数据库(Document-oriented database,也即半结构化数据库)来说,这种方式允许系统将整个文档写到磁盘的一块连续区域上,当需要更新的时候,直接重写一个版本,而不是对文档的某些比特位、分片切除,或者维护一个链式的、非连续的数据库结构。
MVCC 提供了时点(point in time)一致性视图。MVCC 并发控制下的读事务一般使用时间戳或者事务 ID去标记当前读的数据库的状态(版本),读取这个版本的数据。读、写事务相互隔离,不需要加锁。读写并存的时候,写操作会根据目前数据库的状态,创建一个新版本,并发的读则依旧访问旧版本的数据。
一句话讲,MVCC就是用
同一份数据临时保留多版本的方式的方式,实现并发控制。这里留意到 MVCC 关键的两个点:
- 在读写并发的过程中如何实现多版本;
- 在读写并发之后,如何实现旧版本的删除(毕竟很多时候只需要一份最新版的数据就够了);
1.2 实现
MVCC 使用时间戳(TS)、递增的事务 ID(T)实现事务一致性。
MVCC 通过维护多版本数据,保证一个读事务永远不会被阻塞。对象 P 维护有多个版本,每个版本会有一个读时间戳(Read TimeStamp, RTS)和 写时间戳(Write TimeStamp, WTS),事务 Ti 读对象 P 的最新版本,该版本早于事务 Ti 的读时间戳 RTS(Ti)。
事务 Ti 要对 P 执行写操作,如果有其他事务 Tk 同时对 P 操作,则 RTS(Ti)必须要早于 RTS(Tk),即有 RTS(Ti) < RTS(Tk),这样对 Ti 对 P 的写操作才能完成。一般地,如果其他事务拥有 P 的一个更早的读时间戳的情况下,写操作是不能完成的。打个比方就是在存储前面有一道线,只有等你前面的人的完成了他们的事务,你的修改事务才可以提交完成。
重复说一下:每个对象 P 有一个时间戳 TS,如果事务 Ti 想要对 P 执行写操作,(写要先读)事务的读时间戳是 RTS(Ti),如果有其他事务拥有一个比较早的时间戳,有 TS(P) < RTS(Ti),这时事务 Ti 会退出并重新开始。否则,事务 Ti 创建一个 P 的新版本,并设置新版本 P 的时间戳,似的 TS = TS(Ti)。
MVCC 系统明显的缺点是会存储多个版本数据的冗余开销。但同时,读操作永不会被阻塞,这对那些以读操作为主的数据库来说非常重要。MVCC 实现了真的快照隔离(snapshot isolation),然后其他的并发控制方法要么是不完整的快照隔离方式,要么需要较高的性能损耗。
Wikipedia 中的内容有点繁琐,简单地,上面的描述,阐明了在同一数据版本下写操作的限制,已经通过多版本实现快照隔离的优越性。
1.3 示例
| Time | Object1 | Object2 |
|---|---|---|
| 0 | "Foo" by T0 | "Bar" by T0 |
| 1 | "Hello" by T1 |
Time=1的时候数据库的状态如上:
T0 写 Object1 为 "Foo",写 Object2 为 "Bar";之后 T1 写 Object1 为 "Hello",保留 Object2 为原始值。 Object1 的新值将取代 Time=0 时刻的旧值,并提供给 T1提交之后的发生的所有事务。Object1的版本号为0的旧数据会被 GC 掉。
如果有一个长事务 T2,在 T1之后对 Object1和 Object2 进行读操作,同时并行地,有事务 T3 做更新:删除 Object2、增加 Object3="Foo-Bar",在 Time=2 数据的状态如下所示:
| Time | Object1 | Object2 | Object3 |
|---|---|---|---|
| 0 | "Foo" by T0 | "Bar" by T0 | |
| 1 | "Hello" by T1 | ||
| 2 | (delete)by T3 | "Foo-Bar" by T3 |
在 Time=2 Object2有一个新版本:标记删除,同时增加了新对象 Object3 。T2 和 T3 并发执行,T2 看到的是数据在 Time=2 且 T3提交前的版本,这样 T2读到了 Object2="Bar""且Object1="Hello"。
以上就是 MVCC 在不加锁的情况下实现的快照隔离的读的原理。
1.4 历史
最早于1978年,论文『Naming and Synchronization in a Decentralized Computer System』清晰地介绍了 MVCC,这是公认关于 MVCC 最早的工作。
在1981年,论文『Concurrency Control in Distributed Database System』介绍MVCC的一些细节。
目前支持 MVCC 的数据库,包括 DB2、Oracle、Sybase、SQL Server、MySQL、PG 等所有主流数据库,以及 HBase、Couchbase、Berkeley DB 等 NoSQL 数据库
参考
关于 MVCC 的基础的更多相关文章
- 关于 MVCC 的基础【转】
1. 什么是MVCC 1.1 基础概念 MVCC,Multi-Version Concurrency Control,多版本并发控制.MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据 ...
- lightning mdb 源代码分析(4)—MVCC/COW
本博文将描述MVCC和cow技术以及LMDB中如何使用以及实现这两种技术. COW(Copy On Write): COW技术背后的思想是拖延技术,基本方法是假如有多个调用者需要访问的资源,在其初始化 ...
- MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析
文/何登成 导读: 来自网易研究院的MySQL内核技术研究人何登成,把MySQL数据库InnoDB存储引擎的多版本控制(简称:MVCC)实现原理,做了深入的研究与详细的文字图表分析,方便大家理解I ...
- MySQL数据库事务各隔离级别加锁情况--read committed && MVCC
之前已经转载过几篇相关的文章,此次基于mysql 5.7 版本,从测试和源码角度解释一下RR,RC级别为什么看到的数据不一样 先补充一下基础知识 基本知识 假设对于多版本(MVCC)的基础知识,有所了 ...
- InnoDB多版本(MVCC)实现简要分析(转载)
http://hedengcheng.com/?p=148 基本知识 假设对于多版本(MVCC)的基础知识,有所了解.InnoDB为了实现多版本的一致读,采用的是基于回滚段的协议. 行结构 InnoD ...
- innodb mvcc多版本实现
出自:http://hedengcheng.com/?p=148 基本知识 假设对于多版本(MVCC)的基础知识,有所了解.InnoDB为了实现多版本的一致读,采用的是基于回滚段的协议. 行结构 In ...
- 转:InnoDB多版本(MVCC)实现简要分析
InnoDB多版本(MVCC)实现简要分析 基本知识 假设对于多版本(MVCC)的基础知识,有所了解.InnoDB为了实现多版本的一致读,采用的是基于回滚段的协议. 行结构 InnoDB表数据的组织方 ...
- InnoDB多版本(MVCC)实现简要分析
转载自:http://hedengcheng.com/?p=148 基本知识 假设对于多版本(MVCC)的基础知识,有所了解.InnoDB为了实现多版本的一致读,采用的是基于回滚段的协议. 行结构 I ...
- LMDB中的mmap、Copy On Write、MVCC深入理解——讲得非常好,常来看看!
LMDB基本架构 lmdb的基本架构如下: lmdb的基本做法是使用mmap文件映射,不管这个文件存储实在内存上还是在持久存储上.lmdb的所有读取操作都是通过mmap将要访问的文件只读的映射到虚拟 ...
随机推荐
- 现代JVM内存管理方法的发展历程,GC的实现及相关设计概述(转)
JVM区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- 一对TCP协议及OSI简介模式
原文地址: 移步这里
- Poj Roadblocks(次短路)
Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best ...
- 管道通信(使用popen和pclose功能简单的控制管道)
函数原型: FILE *popen(const char * command ,const char *mode) int pclose(FILE * stream) 当心: 采用popen和pclo ...
- 读取xml文件"分析 EntityName 时出错"的解决方案
在涉及到xml与xslt编程的过程中,经常会碰到"分析 EntityName 时出错"的提示,这个不是程序错误,是因为xml文件中使用了一些特殊符号导致的. XML 节点中不 ...
- Android Application.java以及它的作用
What is Application Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application ...
- POJ 1088 滑雪 (动规)
滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 75664 Accepted: 28044 Description Mich ...
- 百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法
原文:百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法 公司的网站改版要求在一个页面显示百度地图.上面要同时显示很多标注点,标注点当然要有提示信息嘛,提 ...
- Ubuntu 12.04 64bit 安装编译GCC 4.1.2 绝对原创
1. 下载并解压源代码: wget http://mirrors.ustc.edu.cn/gnu/gcc/gcc-4.1.2/gcc-4.1.2.tar.bz2 tar jxvf gcc-4.1.2. ...
- Swift # Apple Pay集成
苹果正式开放了Apple Pay支付系统.Apple Pay是一个基于NFC的支付系统,不久将被数以万计的线下零售商店予以支持.即便这项科技并不是彻底的突破性进展,但它足以推动许多公司和零售商来支持这 ...