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

MySQL中的MVCC(r12笔记第35天)
2018年05月17日 04:36 CAMIA观察

分享科技方面的资讯,好玩有趣,让您的茶余饭后不再无聊,欢迎关注评论

最近同事也问了我关于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有力的竞争对手,但是结果让人唏嘘长叹,可以参见:由MySQL中的falcon存储引擎引申的八卦杂谈(r5笔记第23天)

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

MVCC实现

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

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

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

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

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

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

  • idnamecreate versiondelete version
  • 1test1

2)、在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。 比如,针对上面那行记录,事务id为2要把name字段更新,

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

  • idnamecreate versiondelete version
  • 1test12
  • 1new_value2

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

delete from table where id=1;

  • idnamecreate versiondelete version
  • 1new_value23

4)、查询操作:

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

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

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

这样就保证了各个事务互不影响。从这里也可以体会到一种提高系统性能的思路,就是: 通过版本号来减少锁的争用。

另外,只有read-committed和repeatable-read 两种事务隔离级别才能使用MVCC,read-uncommited由于是读到未提交的,所以不存在版本的问题而serializable则会对所有读取的行加锁。

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

配图来源网络,如有侵权联系删除。

作者文章

新浪首页 语音播报 相关新闻 返回顶部