这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
前言: 本篇文章 是我关于MySQL的第11篇文章,水平一般、能力有限。文章写的比较浅,适合新手来看。本篇文章是接着前面的MySQL中存储引擎和事务的关系来讲下多版本控制并发
1. 是什么
Multi-Version Concurrency Control 多版本并发控制简称为MVCC。
什么是多版本并发控制呢?
前文中我们讲到,表数据在进行写入或者更改表结构时会有行级锁和表锁分别锁住此行和此表。
一般情况下,更改一条数据时。会将读取该行数据的查询语句阻塞掉。否则会有幻读的情况发生。
MVCC就是为了解决上述问题而生的,即通过不加锁还能正常读取数据。该方式主要是在InnoDB存储引擎中实现的。
2. 如何实现
MVCC是多版本并发控制,那么它的多版本在什么地方呢?
一般来说,一张表如果想实现多版本。需要在表中增加版本的字段。每次新增时将版本号+1
InnoDB的简化版MVCC实现原理就是偷偷给我们的表增加了一些隐藏字段。
-
DB_TRX_ID :系统版本创建版本号(事务ID)
-
DB_ROLL_PTR:系统的删除版本号(指向上一个版本)
-
DB_ROW_ID:自增主键,当数据库没有主键时生效。
每当提交一个新事务,系统版本号会自增。事务开始时的版本号会作为基础版本号,来和每个查询结果的版本号进行对比。
查询时: 查询比当前事务开始的版本号小的版本数据。也就是事务开始前最后一个版本的数据。并且删除版本号不存在。 新增: 保存当前的系统版本号到DB_TRX_ID字段中。 删除: 保存当前的系统版本号到DB_ROLL_PTR字段中。 更新: 插入一条新数据到表中,并且保存当前的系统版本号到DB_TRX_ID字段中。保存当前的系统版本号到原来那条的DB_ROLL_PTR字段中。
只要保证这两个字段的的正常写入,一般情况下可以不用加行级锁就达到正常读取数据的效果。缺点是版本如果比较多的话会很占空间。
注意:
MVCC 只能在可重复读和读已提交这两个事务隔离级别中工作。
参考文档
《高性能MySQL》