【MySQL】MVCC详解与MVCC实现原理

一、什么是MVCC

MVCC,全称 Multi-Version Concurrency Control ,MVCC是多版本并发控制的全称,是指多版本的并发控制。MVCC是一种并发控制方法。通常,在数据库管理系统中,它用编程语言实现对数据库和事务存储器的并发访问。

MVCC 是一种在读取数据时无需锁定(加锁)即可提高读取效率和并发性的方法。

数据库并发有以下情况:

1、读-读:没有问题。

2、读-写:存在线程安全问题,这可能导致脏读、幻读和不可重复读。

3、写-写:存在线程安全问题,更新可能会丢失。

二、MVCC的实现原理

这里面讲解了,事务的特性、事务的隔离级别,当时说MySQL事务实现原理有单版本控制——锁,以及多版本控制MVCC。

现在我们需要知道,在读已提交RC,Read Committed)和可重复读RR,Repeatable Read)隔离级别下的快照读,都是基于MVCC实现的!

MVCC最大的优点是没有读锁,读写之间没有冲突。在读多写少的OLTP(On-Line Transaction Processing,联机事务处理)应用程序中,读写之间没有冲突非常重要,这大大提高了系统的并发性。

1、MVCC多版本实现

为了让您更直观地理解MVCC的实现原理,这里通过事务更新一行记录的过程的例子,来解释MVCC中多个版本的实现。

假设 ID~……是表中字段的名称(DATA)。最后三个隐藏字段对应对应行的隐藏ID、事务编号和回滚指针,如下图所示:

隐含ID(DB_ROW_ID),6字节,当InnoDB自动生成聚集索引时,聚集索引包括这个DB_ROW_ ID的值。

事务编号(DB_TRX_ID),6字节,它标记了此行最新更新记录的事务ID。每个事务都被处理,其值自动为+1。

回滚指针(DB_ROLL_PT),7个字节,指向当前记录项的回滚段的撤消日志记录,通过该记录可以找到以前版本的数据。

具体更新过程简述如下:

首先,如果数据只是INSERT,则可以认为ID是 1,其他两个字段为空。

当 事务1 更改此行的数据值时,将执行,一、使用独占锁锁定行,记录重做日志;二、将修改前这一行的值复制到Undo日志;三、修改当前行的值,填写事务ID,并使回滚指针指向撤销日志中修改前的行。

接下来,与 事务1 相同。此时,undo 日志中有两行记录,它们由回滚指针连接。

因此,如果撤消日志没有一直被删除,那么当前记录的回滚指针将追溯到创建该行时的初始内容。InnoDB中有一个清除线程,将查询比最旧的活动事务更早的撤消日志并将其删除,从而确保撤消日志文件不会无限增长。

2、MVCC 实现原理

它的实现原理主要是依赖记录中的 3个隐式字段(DB_ROW_ID、DB_TRX_ID、DB_ROLL_PT),undo日志 , Read View 来实现的。

上面我们已经详细介绍了3个隐式字段的含义,总结一下

默认情况下,DB_ROW_ID 是数据库为这行记录生成的唯一隐式主键。DB_TRX_ID 是当前操作记录的事务ID,而 DB_ROLL_PTR 是一个回滚指针,与撤消日志一起使用以指向以前的旧版本。

有两种 undo 日志:insert undo log、update undo log,帮助MVCC的撤销的本质是update undo log 。事实上,撤消日志是回滚段中的旧记录链。(MySQL日志系统的详解:(待补充))。

3、什么是 Read View

什么是 Read View

Read View 是事务执行快照读取操作时生成的视图。在事务执行快照读取时,将生成数据库系统的当前快照,并记录和维护系统当前活动事务的ID(当每个事务启动时,将分配一个ID,该ID是增量的,因此最新事务的ID值更大)。

当我们使用select读取数据时,此时会有许多版本的数据,但我们不知道要读取哪个版本。

此时,我们依赖readview来限制我们可以读取的版本。只有通过readview才能知道我们可以阅读哪个版本。

3.1、Read View 解析

Read View主要用于进行可见性判断,也就是说,当我们为事务执行快照读时,我们会为记录创建一个读取视图 Read View。以判断当前事务可以看到哪个版本的数据。它可能是当前期间的最新数据,也可能是记录 undo log 中某个版本的数据。

读取视图遵循可见性算法,主要是要修改的数据的最新记录中的 DB_TRX_ID (即当前事务ID),并与系统中其他活动事务的ID(由读取视图 Read View 维护)进行比较。

如果 DB_TRX_ID 跟 Read View 属性不符合可见性,通过 DB_ROLL_PTR 回滚指针在撤消日志Undo Log中的 DB_TRX_ID 比较中检索数据库(遍历链表的 DB_TRX_ID)。

遍历链接列表的DB _ TRX_ ID(从链的开始到链的结束,即从最近的修改),直到找到满足特定条件的 DB_TRX_ID , 那么这个 DB_TRX_ID 所在的旧记录就是当前事务能看见的最新老版本。

3.2、Read View 含义

在一个 Read View 快照中主要包括以下这些字段:

m_ids,表示生成 Read View 时当前系统中活动读/写事务的事务ID列表

min_trx_id,表示生成 Read View 时当前系统中活动读/写事务中最小的事务ID,即 m_ids 最小值

max_trx_id,表示生成 Read View 时应分配给系统中下一个事务的ID值

creator_trx_id,表示生成 Read View 的事务的事务ID

3.3、Read View 如何判断版本链可用

trx_id == creator_trx_id,可以访问这个版本;

trx_id < min_trx_id,可以访问这个版本;trx_id > max_trx_id,不可以访问这个版本;

min_trx_id <= trx_id <= max_trx_id,如果 trx_id 在 m_ids 中不可以访问,反之可以

三、当前读,快照读与MVCC

1、什么是当前读和快照读

1.1、当前读

select lock in share mode (共享锁), select for update; update; insert; delete (排他锁)这些操作都是一种当前读。

它读取最新版本的记录,读取时,它还确保其他并发事务无法修改当前记录,并锁定读取的记录。

1.2、快照读

不加锁的 select 操作就是快照读,即无锁的非阻塞读取;

快照读的前提是隔离级别不是串行级别,在串行级别下读取的快照将退化为当前读取,发生快照读的原因是基于提高并发性能的考虑。

快照读的实现基于多版本并发控制,即MVCC。MVCC可以被认为是行锁的变体,但在许多情况下,它避免了锁操作并减少了开销;由于它基于多个版本,也就是说,读取的快照可能不是数据的最新版本,而是以前的历史版本

MVCC的设计目的是在不锁定读写冲突,这种读取指的是快照读取,而不是当前读取。

当前的读取实际上是一个锁操作,这是悲观锁的实现

2、快照读、当前读与MVCC辨析

MVCC多版本并发控制的概念是“维护一个数据的多个版本,以便读写操作之间没有冲突”。

因为MVCC只是一个抽象的概念,为了实现这样的概念,MySQL需要提供特定的功能来实现它。“快照读取是MySQL MVCC理想模型的非阻塞读取功能之一”。

相对而言,当前读是悲观锁的具体功能实现,快照阅读本身也是一个抽象概念。

3、MVCC 只在 RC 和 RR 隔离级别下工作

一、 在RC(Read Commited )的隔离级别下,每次快照读取都会生成并获得最新的 readview

二、在RR(Repeatable Read)隔离级别,只有读取同一事务的第一个快照才能创建 readview。每个后续快照读取都使用相同的 readview,因此每个查询结果都相同。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容