MVCC介绍

简介

MVCC(Multi-Version Concurrency Control)即多版本并发控制。
MySQL的大多数事务型(如InnoDB,Falcon等)存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,他们一般都同时实现了MVCC。当前不仅仅是MySQL,其它数据库系统(如Oracle,PostgreSQL)也都实现了MVCC。值得注意的是MVCC并没有一个统一的实现标准,所以不同的数据库,不同的存储引擎的实现都不尽相同。

作为MySQL中使用最广泛的存储引擎,本文主要讨论的是InnoDB的多版本并发控制的实现

MVCC优缺点

MVCC在大多数情况下代替了行锁,实现了对读的非阻塞,读不加锁,读写不冲突。缺点是每行记录都需要额外的存储空间,需要做更多的行维护和检查工作。

MVCC的实现原理

undo log

为了便于理解MVCC的实现原理,这里简单介绍一下undo log的工作过程

在不考虑redo log 的情况下利用undo log工作的简化过程为:

序号

动作

1

开始事务

2

记录数据行数据快照到undo log

3

更新数据

4

将undo log写到磁盘

5

将数据写到磁盘

6

提交事务

1)为了保证数据的持久性数据要在事务提交之前持久化
2)undo log的持久化必须在在数据持久化之前,这样才能保证系统崩溃时,可以用undo log来回滚事务

Innodb中的隐藏列

Innodb通过undo log保存了已更改行的旧版本的信息的快照。
InnoDB的内部实现中为每一行数据增加了三个隐藏列用于实现MVCC。

列名

长度(字节)

作用

DB_TRX_ID

6

插入或更新行的最后一个事务的事务标识符。(删除视为更新,将其标记为已删除)

DB_ROLL_PTR

7

写入回滚段的撤消日志记录(若行已更新,则撤消日志记录包含在更新行之前重建行内容所需的信息)

DB_ROW_ID

6

行标识(隐藏单调自增id)

结构

数据列

..

DB_ROW_ID

DB_TRX_ID

DB_ROLL_PTR

MVCC工作过程

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

SELECT

InnoDB 会根据两个条件来检查每行记录:

  • InnoDB只查找版本(DB_TRX_ID)早于当前事务版本的数据行(行的系统版本号<=事务的系统版本号,这样可以确保数据行要么是在开始之前已经存在了,要么是事务自身插入或修改过的)
  • 行的删除版本号(DB_ROLL_PTR)要么未定义(未更新过),要么大于当前事务版本号(在当前事务开始之后更新的)。这样可以确保事务读取到的行,在事务开始之前未被删除。

INSERT

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

DELETE

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

UPDATE

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

mvcc的应用

 

 

原理及好处

 

MVCC:多版本并发控制(MVCC,Multiversion Currency Control)。一般情况下,事务性储存引擎不是只使用表锁,行加锁的处理数据,而是结合了MVCC机制,以处理更多的并发问题。Mvcc处理高并发能力最强。

但系统开销 比最大(较表锁、行级锁),这是最求高并发付出的代价。

 

 

隐藏字段

 

** InnoDB实现MVCC的方法是,它存储了每一行的三个额外的隐藏字段:**

 

1.DB_TRX_ID:一个6byte的标识,每处理一个事务,其值自动+1 #下面提到的“创建时间”和“删除时间”记录的就是这个DB_TRX_ID的值 #如insert、update、delete操作时,删除操作用1个bit表示。 #DB_TRX_ID是最重要的一个,可以通过语句“show engine innodb status”来查找

 2.DB_ROLL_PTR: 大小是7byte,指向写到rollback segment(回滚段)的一条undo log记录 (update操作的话,记录update前的ROW值)

3.DB_ROW_ID: 大小是6byte,该值随新行插入单调增加。 #当由innodb自动产生聚集索引时聚集索引(即没有主键时,因为MYSQL默认聚簇表,会自动生成一个ROWID) #包括这个DB_ROW_ID的值, #不然的话聚集索引中不包括这个值,这个用于索引当中。

 

应用场景

 

1.READ UNCOMMITTED ,不适用MVCC读,可以读到其他事务修改甚至未提交的 2.READ COMMITTED ,其他事务对数据库的修改,只要已经提交,其修改的结果就是可见的, 与这两个事务开始的先后顺序无关,不完全适用于MVCC读, 3.REPEATABLE READ,可重复读,完全适用MVCC,只能读取在它开始之前已经提交的事务对数据库的修改, 在它开始以后,所有其他事务对数据库的修改对它来说均不可见

4.SERIALIZABLE ,完全不适合适用MVCC,这样所有的query都会加锁,再它之后的事务都要等待

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值