MySQL之MVCC


图片来自B站:https://www.bilibili.com/video/BV1Yc411N7tK/?spm_id_from=333.788.recommend_more_video.1&vd_source=7ac79926da488e4e7af86f12cf1f5d8e

MVCC是啥?

多版本并发控制,多版本是指MySQL维护的行记录,他不是唯一一个版本,有很多版本
并发控制是指,多个事务操作同一个行记录时,MySQL会返回多个版本记录中的某个版本。
仅在innoDB引擎,仅在读已提交和可重复读隔离级别下**快照读(普通select语句)**时的版本控制
图片.png

MVCC原理

隐藏字段和undolog版本链

每个行记录里有一些隐藏字段,其中有trx_id,rollpoint,trx_id是操作了这条行记录的事务的id,rollpoint是回滚指针,它指向这个记录的另一个版本,形成一个链表,undolog版本链
比如说这些都是同一条记录,只是不同版本,通过rollpoint连起来,上面是最新的记录
图片.png

ReadView

再说说ReadView,ReadView决定了并发控制的时候MySQL到底返回哪个版本。
当一个事务开启时(活跃事务),ReadView保存了MySQL里所有活跃事务的列表(活跃事务是指开启但是未提交的事务)
然后重点来了,ReadView里有四个字段

  • 当前数据库里所有活跃事务(不包括创建ReadView的本事务):m_ids

  • 这些活跃事务里id最小的事务:min_trx_id

  • 创建该ReadView时,MySQL应该分配给下一个事务的id。也就是此时全局事务中最大事务id+1:max_trx_id

  • 创建该ReadView的事务的id:creater_trx_id

注意
一个值得注意的点,ReadView里面的所有活跃事务id列表并不包括创建这个ReadView的当前事务的id,这个事务的id有单独的字段存放。

然后,并发场景下,一个事务访问一条行记录时,MySQL会通过ReadView的可见性规则,给出对应的行记录版本。
ReadView可见性规则如下
图片.png

读已提交、可重复读下不同的ReadView

读已提交

先想想这个隔离级别下会出现啥问题,幻读,可重复读。
在这个隔离级别下,每次快照读(普通select语句)都会生成新的ReadView

说人话:我select一次就来了个新ReadView,假如一个事务有两条select,查的都是同一个数据,查完第一次,生成了个新的ReadView,那有可能第二次查,查出来的数据就不是第一次的了,这就是不可重复读

可重复读

在这个隔离级别下,只有第一次快照读(普通select语句)生成ReadView,后面直接复用
所以不管select几次,只要在可重复读隔离级别下,就不可能发生一个事务里读到不同数据的情况。

MVCC能干啥?

解决阻塞

当一个行记录加锁时,可能会产生阻塞,而如果一个普通select语句来查,这个行记录,就会走MVCC机制

可重复读隔离级别下解决快照读(普通select)时发生的幻读

在可重复读隔离级别下,MVCC在快照读(普通select语句)的情况下能避免出现幻读。
因为他只在事务A开启时生成一个ReadView,即时有其他事务B插入数据,那么事务A后面快照读的时候也不影响,因为用的还是最初的ReadView,返回的还是最初的版本。

说人话面试题

什么是MVCC?

多版本并发控制,在innoDB引擎下,快照读的前提下,通过隐藏字段、undolog版本链,ReadView协调合作下,会返回不同版本的行记录。

MVCC原理

MySQL行记录有隐藏字段,trx_id和rollpoint,trx_id是事务id,相当于版本号,rollpoint是回滚指针,指向旧版本的行记录。
事务开启时会创建ReadView,里面保存着开启事务时数据库里所有的活跃事务(开启但未提交的事务)
当有事务快照读(普通select)一个行记录的时候,会根据ReadView可见性规则比较这个事务的id和行记录的ReadView里的活跃事务id,返回不同的行记录版本。

读已提交和可重复读隔离级别下MVCC有什么不同

读已提交隔离级别下,事务开启后,每次快照读都会创建一个ReadView,这有可能发生不可重复读的现象
可重复读隔离级别下,事务开启创建一个ReadView,后面的快照读都会复用这个,所以避免不可重复读

MVCC是如何解决幻读的?

MVCC在可重复读的隔离级别下,能解决快照读的幻读情况,因为事务只创建一个ReadView

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值