Mysql 的InnoDB事务方面的 多版本并发控制如何实现 MVCC

MVCC:Multi-Version Concurrency Control 多版本并发控制。笔者用自己的话对MVCC做一个总结:通过某个时间点上的数据快照对数据的版本控制,目的是为了避免使用各种锁影响并发性能

●MySQL锁机制 
说到锁,MySQL里提供了几种锁机制 
读写锁 
表锁 (MYISAM使用了表锁)
行级锁
 (InnoDB使用了行级锁)

第一点:

MVCC并不是MySql独有的,Oracle,PostgreSQL等都在使用。

MVCC并没有简单地使用行锁,而是使用“行级别锁”(row-level locking)。

MVCC的基本原理是:

MVCC的实现,通过保存数据在某个时间点的快照来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,同时也意味着在同一个时刻不同事务看到的相同表里的数据可能是不同的。

MVCC的基本特征:

  • 每行数据都存在一个版本,每次数据更新时都更新该版本。
  • 修改时Copy出当前版本随意修改,各个事务之间无干扰。
  • 保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback)

InnoDB存储引擎MVCC的实现策略:

在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(可能为空)。这里的版本号并不是实际的时间值,而是系统版本号。每开始 个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。

每个事务又有自己的版本号,这样事务内执行CRUD操作时,就通过版本号的比较来达到数据版本控制的目的。具体做法见下面的示意图。

  

MVCC具体的操作如下:

SELECT:InnoDB会根据以下两个条件检查每行记录:

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

2)行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

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

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

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

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

MVCC只在REPEATABLE READ和READ COMMITED两个隔离级别下工作,其它两个隔离级别和MVCC不兼容。

)

把及时总结当成一种习惯

mysql的mvcc(多版本并发控制)

我们知道,mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能。

什么是多版本并发控制呢 ?其实就是在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号,

而每一个事务在启动的时候,都有一个唯一的递增的版本号。

1、在插入操作时 : 记录的创建版本号就是事务版本号。

比如我插入一条记录, 事务id 假设是1 ,那么记录如下:也就是说,创建版本号就是事务版本号。

id   name   create version   delete version  
1 test   1  

2、在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。

比如,针对上面那行记录,事务Id为2 要把name字段更新

update table set name= ‘new_value‘ where id=1;

id     name   create version   delete version  
1   test   1 2        
1   new_value   2  

3、删除操作的时候,就把事务版本号作为删除版本号。比如

delete from table where id=1;

id   name   create version   delete version  
1 new_value 2 3  

4、查询操作:

从上面的描述可以看到,在查询时要符合以下两个条件的记录才能被事务查询出来:

1) 删除版本号 大于 当前事务版本号,就是说删除操作是在当前事务启动之后做的。

2) 创建版本号 小于或者等于 当前事务版本号 ,就是说记录创建是在事务中(等于的情况)或者事务启动之前。

这样就保证了各个事务互不影响。从这里也可以体会到一种提高系统性能的思路,就是:

通过版本号来减少锁的争用。

另外,只有read-committed和 repeatable-read 两种事务隔离级别才能使用mVcc

read-uncommited由于是读到未提交的,所以不存在版本的问题

而serializable 则会对所有读取的行加锁。

参考:mysql 的MVCC(多版本并发控制):http://www.cnblogs.com/dongqingswt/p/3460440.html

多版本并发控制:http://blog.csdn.net/xifeijian/article/details/45230053

时间: 2024-10-14 09:51:36

Mysql 的InnoDB事务方面的 多版本并发控制如何实现 MVCC的相关文章

Java面试05|MySQL及InnoDB引擎

1.InnoDB引擎索引 InnoDB支持的索引有以下几种: (1)哈希索引 (2)全文索引 (1)B+树索引 又可以分为聚集索引与辅助索引 索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER TABLE来给表增加索引.删除索引可以利用ALTER TABLE或DROP INDEX语句来实现. (1)使用ALTER TABLE语句创建索引.语法如下: alter table table_name add index index_name (colu

MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析

文/何登成 导读:   来自网易研究院的MySQL内核技术研究人何登成,把MySQL数据库InnoDB存储引擎的多版本控制(简称:MVCC)实现原理,做了深入的研究与详细的文字图表分析,方便大家理解InnoDB存储引擎实现的多版本控制技术(简称:MVCC). 基本知识 假设对于多版本控制(MVCC)的基础知识,有所了解.MySQL数据库InnoDB存储引擎为了实现多版本的一致性读,采用的是基于回滚段的协议. 行结构 MySQL数据库InnoDB存储引擎表数据的组织方式为主键聚簇索引.由于采用索引

InnoDB事务日志(redo log 和 undo log)详解

数据库通常借助日志来实现事务,常见的有undo log.redo log,undo/redo log都能保证事务特性,undolog实现事务原子性,redolog实现事务的持久性. 为了最大程度避免数据写入时io瓶颈带来的性能问题,MySQL采用了这样一种缓存机制:当query修改数据库内数据时,InnoDB先将该数据从磁盘读取到内存中,修改内存中的数据拷贝,并将该修改行为持久化到磁盘上的事务日志(先写redo log buffer,再定期批量写入),而不是每次都直接将修改过的数据记录到硬盘内,

[转帖]2019-03-26 发布 深入理解 MySQL ——锁、事务与并发控制

深入理解 MySQL ——锁.事务与并发控制 https://segmentfault.com/a/1190000018658828 太长了 没看完.. 数据库 并发  mysql 639 次阅读  ·  读完需要 46 分钟 21 本文首发于 vivo 互联网技术微信公众号 https://mp.weixin.qq.com/s/JF...作者:张硕 本文对 MySQL 数据库中有关锁.事务及并发控制的知识及其原理做了系统化的介绍和总结,希望帮助读者能更加深刻地理解 MySQL 中的锁和事务,从

SQL事务的四种隔离级别和MySQL多版本并发控制

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的那些改变时可见的,那些是不可见的.低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销. ReadUncommitted(读取未提交内容) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结构.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取未提交的数据,也被称之为脏读(Dirty Read) ReadCommitted(读取提交内容) 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的).它

《高性能MySQL》读书笔记之 MySQL锁、事务、多版本并发控制的基础知识

1.2 并发控制 1.2.1 读写锁 在处理并发读或写时,通过实现一个由两种类型的锁组成的锁系统来解决问题.这两种类型的锁通常被称为 共享锁(shared lock) 和 排它锁(exclusive lock),也叫读锁(read lock)和写锁(write lock). 读锁是共享的,或者说是不互相阻塞的.多个客户端可以在同一时刻读取同一个资源,而互不干扰.写锁则是排他的,也就是说一个写锁会阻塞其他写锁和读锁. 1.2.2 锁粒度 为了提高共享资源的并发性,尽量只锁定需要修改的部分数据,而不

Mysql InnoDB事务

事务特点 ACIDATOMICITY:原子性 一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性 CONSISTENCY:一致性 数据库总是从一个一致性的状态转换到另一个一致性的状态. ISOLATION:隔离性 通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的. DURABILITY:持久性 一旦事务提交,则其所做的修改不会永久保存到数据库. 隔离级别:READ

MySQL Innodb 事务实现过程相关内容的整理

MySQL事务的实现涉及到redo和undo以及purge,redo是保证事务的原子性和持久性:undo是保证事务的一致性(一致性读和多版本并发控制):purge清理undo表空间背景知识,对于Innodb表中的行每一行包括:6字节的事务ID(DB_TRX_ID)字段: 用来标识最近一次对本行记录做修改(INSERT|UPDATE)的事务的标识符, 即最后一次修改(INSERT|UPDATE)本行记录的事务id.7字节的回滚指针(DB_ROLL_PTR)字段: 指写入回滚段(ROLLBACK s

MySQL · 引擎特性 · InnoDB 事务系统

MySQL · 引擎特性 · InnoDB 事务系统 前言 关系型数据库的事务机制因其有原子性,一致性等优秀特性深受开发者喜爱,类似的思想已经被应用到很多其他系统上,例如文件系统等.本文主要介绍InnoDB事务子系统,主要包括,事务的启动,事务的提交,事务的回滚,多版本控制,垃圾清理,回滚段以及相应的参数和监控方法.代码主要基于RDS 5.6,部分特性已经开源到AliSQL.事务系统是InnoDB最核心的中控系统,涉及的代码比较多,主要集中在trx目录,read目录以及row目录中的一部分,包括