MySQL中的MVCC(r12笔记第35天)

Posted 杨建荣的学习笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL中的MVCC(r12笔记第35天)相关的知识,希望对你有一定的参考价值。

最近同事也问了我关于mysql MVCC的一些问题,我觉得这个话题蛮有意思, 而之前似乎也没有总结过,就参考了一些资料,把一些内容摘录出来。

什么是MVCC

以下内容摘自:http://www.jdon.com/repository/database-mvcc.html

关系数据库管理系统使用MVCC(Multiversion Concurrency Control多版本并发控制)来避免写操作堵塞读操作的并发问题,MVCC也就是通过使用数据的多个版本保证并发读写不冲突的一种机制,不同的数据库有不同的实现,这也是数据库系统让人头疼的地方.

MVCC的两种不同实现方式

以下内容摘自:http://www.jdon.com/repository/database-mvcc.html

  第一种实现方式是将数据记录的多个版本保存在数据库中,当这些不同版本数据不再需要时,垃圾收集器回收这些记录。这个方式被PostgreSQL和Firebird/Interbase采用,SQL Server使用的类似机制,所不同的是旧版本数据不是保存在数据库中,而保存在不同于主数据库的另外一个数据库tempdb中/

  第二种实现方式只在数据库保存最新版本的数据,但是会在使用undo时动态重构旧版本数据,这种方式被Oracle和MySQL/InnoDB使用。

MVCC是为了解决什么问题?

以下摘自 :http://blog.csdn.net/whoamiyang/article/details/51901888

  • 大多数的MYSQL事务型存储引擎,如,InnoDB,Falcon以及PBXT都不使用一种简单的行锁机制.事实上,他们都和MVCC–多版本并发控制来一起使用.悲剧的是Falcon这个存储引擎过早夭折,原本是InnoDB有力的竞争对手,但是结果让人唏嘘长叹,可以参见:

  • 大家都应该知道,锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.

MVCC实现

  MVCC是通过保存数据在某个时间点的快照来实现的. 不同存储引擎的MVCC. 不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制.

   InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,分别保存了这个行的创建时间,一个保存的是行的删除时间。这里存储的并不是实际的时间值,而是系统版本号(可以理解为事务的ID),没开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID


以下内容参考自:http://blog.sina.com.cn/s/blog_d13b2a8f0102wnaq.html

做了简单修改,我们做一些简单的例子来说明。

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 则会对所有读取的行加锁。

   当然上面的内容都是二次吸收,做了一些过滤和简单总结,后续会持续总结和认真分析,对比一下Oracle和MySQL MVCC的异同,MVCC的缺陷等。




以上是关于MySQL中的MVCC(r12笔记第35天)的主要内容,如果未能解决你的问题,请参考以下文章

swingbench压测Oracle小记(r12笔记第19天)

sandbox和MHA快速测试(r12笔记第32天)

IT老齐架构300讲笔记(030) MySQL MVCC机制

笔记

浅谈MySQL Group Replication(r11笔记第80天)

《MySQL技术内幕 InnoDB存储引擎 》学习笔记