搞懂mysql中的mvcc机制

MVCC的介绍

mvcc称为多版本并发控制。这里有两个关键字,一个是多版本,一个是并发。

使用的主要目的

mvcc的出现是为了解决读写不冲突的问题,让我们MySQL在进行数据更改的时候,依然可以进行无锁去读。

基础知识

在搞清楚mvcc的时候,我们必须要搞清楚几个基础知识。

第一在MySQL的锁当中,无论你上的是独占锁还是共享锁,在修改数据的时候都是不可读不可写的。

读写问题如何解决

而在咱们MySQL的大多数场景当中,是以读为主,如果每一次修改都阻塞我们去读,那么性能就不会很好。

这个事情不可避免,那怎么样可以解决这种问题呢?

就是让读和写发生在不同的数据版本。不要绕让他们读同一份数据就可以了。于是就产生了undo log日志。undo log日志会在更新语句之前将原有的数据记录为历史版本。将最新的数据记录为当前版本。

多版本

所以此时会产生两种读操作,一种叫当前读,一种叫快照读。快照读其实读的是历史版本,而当前读读的是最新版本。

当前版本和历史版本通过一个隐藏字段叫roll point来进行互相的连接。这就是MVCC当中的多版本的含义。

并发控制

接下来是并发控制。

所以现在最大的问题就是当多个事务同时产生,需要访问相同数据的时候,他们应该如何选择与之匹配的版本。这就叫版本控制。

MySQL通常是通过事务ID来进行具体的版本选择,MySQL会为每一个事务分配一个具体的事务ID。这个事务ID由一个全局的递增变量来进行控制,每一次修改数据,都会将修改这个数据的事务ID,存入一个隐藏字段叫txid当中。

于是每一个版本的数据都会多一个字段叫事务ID。我们可以根据这个事务ID进行版本选择。

当然,仅仅有这些还不够,在有大量并发事务产生的时候,会产生很多的事务ID。这些有的事务是已经被提交的,有的事务是尚未提交正在运行的。在众多的事务当中,选择一个合适的版本并不是一件容易的事

readview

readview叫读视图或者叫读快照。实际上一个readview就是c语言里边的一个结构体,里面包含一些数据。如果你不懂结构体,你就把它当作Java里边的一个类。然后里边的数据当成成员变量理解。这些成员变量包含以下内容:

  1. 当前事务的ID
  2. 预分配事务的ID(就是下一次分配事务的时候的那个ID)
  3. 正在运行但尚未提交的ID所组成的一个数组

根据读视图选择数据版本的方法

当开启一个事务并进行select操作的时候,就会生成一个读视图。根据读视图来选择数据版本的方式如下:

  1. 他会从当前数据开始,沿着版本链,逐个和读视图进行事务ID对比。如果当前最新的数据和当前咱们的事务ID一样,那直接返回最新数据的版本就可以了。说明没有其他的事务在操作逐个数据。
  2. 但如果发现当前数据的事务ID和我们当前事务的ID不一致。那就要判断当前数据的这个事务ID在不在这个未提交的事务ID列表当中。这个在咱们readview当中也是有保存的。如果不在,说明这个事务已经被提交。这个数据也是可以被读取的。如果在就说明当前正在运行的事务正在修改这个数据。那我们就不要去读这个数据。要沿着版本链,继续找下一条可用的数据。通过对历史版本的回溯对比,我们总能找到适合当前事务的数据进行读取。这就是数据版本的选择过程。

读已提交中不可重复读问题

大家都知道对于RC,也就是我们的读已提交的事务隔离级别,是存在不可重复读的问题。

MySQL又是怎么解决的呢?

在RC级别,每次select语句都会产生一个新的读视图,所以每次读取可能会产生不一样的数据。

可重复读解决不可重复读的原理

而在RR级别,也就是咱们的可重复读的隔离级别下,通常第一次select语句会产生一个读视图,在当前事务中,以后每次其他的select语句都复用第一次产生的readview

这样就可以保证在一个事务当中,每一次进行select都可以得到相同的数据版本。这样就解决了咱们的不可重复读问题。

串行化

串行化相当于禁用了历史版本。每一次读取或修改必须使用当前版本。这样的话,性能是很差的。

参考资料每日八股文~五分钟搞懂mysql中的mvcc机制

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值