MVCC浅学

1.什么是MVCC

​ MVCC即多版本并发控制,主要是为了提高数据库的并发性能。

​ 同一行数据平时发生读写请求时,会上锁阻塞住,这是其他事务就无法访问这行数据。但MVCC用更好的方式去处理—写请求,做到在发生读–写请求冲突时不用加锁

​ 这个读指的是快照读,而不是当前读,当前读是一种加锁操作,是悲观锁。

2.当前读

​ 它读取的数据记录,都是当前最新的版本,会对当前读取的数据进行加锁,防止其他的事务对其进行修改,是悲观锁的一种操作,以下操作都是当前读:

  • select lock in share mode(共享锁)
  • select for update(排他锁)
  • update(排他锁)
  • insert(排他锁)
  • delete(排他锁)
  • 串行化事务隔离级别
3.快照读

​ 快照读的实现是基于多版本并发控制,即MVCC,这个多版本指的是数据的多版本,那么快照读读到的数据不一定是当前的最新数据,有可能是之前的历史版本的数据,以下是快照读操作:

  • 不加锁的select操作(注:事务级别不是串行化)
4.MVCC常见日志
4.1 undo日志

​ undo log中存入的是最新版本之前旧版本的数据,如下图理解:
在这里插入图片描述

4.2 ReadView

​ ReadView中会存入当前未提交事务的id号已创建事务(包括未提交和已提交)的最大事务id号,然后进行比对,有以下参数:

  • m_ids:表示生成"ReadView"时当前系统中活跃的读写事务的"事务id"列表,活跃的读写事务指的是没有commit的事务id号
  • min_trx_id:表示当前系统中活跃的读写事务中的最小的"事务id",也就是"m_ids"中的最小值
  • max_trx_id:表示生成ReadView时系统应该分配给下一个事务的id值,比如现在ReadView中有1、2、3三个id值,那么系统下一个要分配的id值就应该是4,这个"max_trx_id"就是4
  • creator_trx_id:表示生成该"ReadView"的事务的"事务id"
4.3 ReadView判断版本链的哪个版本可用,比较规则
  • trx_id==creator_trx_id:可以访问这个版本
  • trx_id<min_trx_id:可以访问这个版本
  • trx_id>max_trx_id:不可以访问这个版本
  • min_trx_id<=trx_id<=max_trx_id:如果trx_id在m_ids是不可以访问这个版本的,反之可以
4.4 读已提交

​ 在读已提交的隔离级别下,每一次select都会产生一个ReadView,当第一个select产生ReadView时,查询到的语句可能是一个;当第二个select产生另外一个ReadView,查询到的语句可能就是另外一个;两次查询的数据不一致,所以就会产生不可重复读的问题。

4.5 可重复读

​ 在可重复读的隔离级别下,一个事务只会产生一份ReadView,一个事务共用一个ReadView,版本链就不会变,所以在"可重复读"的隔离级别下,就会解决不可重复读的问题。

4.6 可重复读的隔离级别下解决幻读

​ 在可重复读的隔离级别下,只会产生一份ReadView,那么在这个事务中进行多次select就不会产生幻读,但这只是表面上解决了幻读,实际上其他事务还是会插入数据,只不过在快照读下读不到插入的数据。

​ 真正解决幻读是当前读使用临键锁解决的幻读问题,当有以下查询语句时:

#当前读,临键锁会将id>3的数据全部锁起来,其他事务就不能插入数据,就在本质上解决了幻读问题
select * from user where id>3 for update
5.比较规则举例

第一个select
在这里插入图片描述

在这里插入图片描述

第二个select
在这里插入图片描述

在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值