关于MySQL如何使用MVCC(多版本控制)来保证在并发的情况下数据的一致性

        MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了MVCC(即多版本并发控制);其实不仅是MySQL,包括Oracle等其他的数据库系统也都实现了MVCC,各自实现的机制也都不尽相同,因为MVCC并没有一个统一的实现标准。

        简单说一下何为MVCC,多版本并发控制可能有点过于书面难以理解,其实可以看做是行级锁的一个变种,但是在很多的情况下并没有具体的加锁操作,比起加锁效率更高。各个数据库系统虽然实现MVCC机制的方式不同(比较典型的有乐观并发控制和悲观并发控制),但是大都实现了非阻塞的读操作,而写操作也只需要锁定必要的行。

       再说一下MySQL是如何实现MVCC的,其实通过保存数据再某个时间点的快照来实现的。就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。我在看书到这里的时候都还是有点懵逼的,接着往下看就会慢慢清楚了。

      下面以InnoDB简单的说一下MVCC究竟工作原理是怎么样的:

       InnoDB中的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存了行的过期时间(或者删除时间),当然都不是具体的时间值,而是系统版本号。每一个新的事务开始,系统版本号都会自动递增。事务开始的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

      用通俗一点的方式描述一下,见图:

如果所示,假如一张表中加入了三条数据,后面两个是隐藏的两列,假设开始时间这一隐藏列的系统版本号为1

此时A事务开始执行,则A事务的事务版本号等于当前的系统版本号三行数据都为1

然后B事务也开始执行,删掉其中第二条数据,则此时数据如下图:

B事务执行完后提交事务了,此时A事务在提交时就只会读取跟它的事务版本号一样的数据或者小于它的事务版本好的数据,则三条数据都被读取了。从上面的分析,很简洁的描述了MVCC是如何来进行并发控制得,因为保存了快照数据,就说明在B事务删除数据二的时候就已经把数据二的数据保存了并且系统版本号也增加了,出现了两个版本的数据,事务A也通过自身的事务版本号和系统版本号进行比较读取了正确的数据。

OK,最后再根据各个方法细说一遍,能够更加的清楚

SELECT的时候InnoDB会根据以下的两个条件检查每行的数据:

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

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

INSERT

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

DELETE

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

UPDATE

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

相信这些就能够非常明白InnoDB的MVCC的实现原理了;这么做减少了加锁,提升了数据库系统的性能而且也能保证数据的正确性,但是不足的地方是每一行的记录都需要额外的存储空间,需要做更多维护和检查的工作。

注意:MVCC只在REPEATABLE READ(可重复读)和READ COMMITTED(读已提交)两个隔离级别下工作

 

最后,如果觉得讲的还算清楚的朋友点个赞,大半夜熬夜写博客不容易

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值