对于MySQL的MVCC机制的理解

并发事会带来哪些问题?

  • 脏读(Dirty read)
    • 一个事务读取了另一个事务还没有提交的数据;
  • 不可重复读(Unrepeatableread)
    • 同一个事务多次读取一条记录,发现该记录中某些值被修改过;
  • 幻读(Phantom read)
    • 同一个数据在多次查询数据时,会出现数据量不一致的情况,也就是把其他事务插入的数据也查询到了;

其中幻读和不可重复读有些类似,区别:

  • 幻读是指同样的一条查询语句,前后两次读取,数据的数量发生了改变;
  • 不可重复读是指的同一批数据,前后两次读取,这一批数据的值发生了变化;

以上一笔带过,以下主角登场;

如何解决幻读

  • 修改隔离级别改为可串行化,但是效率非常低,可串行化的意思就是说当你开启事务之后,其他事务都不可以进行操作了,只有当你提交完事务之后才可以操作,实际生产中不可能使用此方法;
  • 使用MVCC(多版本并发控制)解决幻读;

MVCC(多版本并发控制)

  • MVCC只能在可重复读和读已提交两个隔离级别下工作,和其他隔离级别是不兼容的,因为读未提交总是读取最新的数据,而可串行化对所有数据都会加锁。

  • MVCC比单纯的加锁更高效,MVCC只在可重复读读已提两个隔离级别下工作

MVCC主要作用(解决了什么问题):

早期数据库不论读取还是写入,都用锁来实现。但是锁会带来性能的问题,MVCC就是MySQL对于读的一种优化方案。
在使用MVCC中,对于任何修改的操作,都不会直接覆盖掉原数据,而是产生一个新老版本共存的状态,根据版本号去区分,使得读取时可以完全不加锁,这样读取数据时,MVCC根据版本号就会判断出应该读取哪些数据,完全不用加锁,MVCC存在的意义就是使MySQL读写不冲突。

一句话概括:他就是一个行级锁的变种,读数据无需加锁、读写不冲突,系统开销更低。

InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现。

  • 一个保存了创建事务id
  • 一个保存了删除事务id

在插入数据的时候,删除的事务id是空的
在执行删除操作时,mysql会在底层记录删除行的删除事务id,对于更新操作原数据并不会真正的被更新掉,只是会隐藏,然后再新增一条数据(暂时可以这么理解,其实底层是使用undo log完成的),mysql会在底层新增一行相同的数据,并记录好对应的创建事务id。

当然存储的并不是真实的时间而是系统版本号。每开始一个新的事务,系统版本号都会自动新增。事务开始时刻的系统版本号会作为事务的版本号,用来查询到每行记录的版本号进行比较。

MVCC在可重复读隔离级别下Mysql是如何工作的:

开始新一个事务时,该事务的版本号肯定会大于当前所有数据行快照的创建版本号

select操作:

InnoDB只查找版本早于当前事务版本的数据行,这样就可以确保查询到的数据在此事务操作之前就已经存在了,要么是事务自身插入或者修改过的,会过滤掉此事务开始之后的数据。
行的删除版本号要么未定义,要么大于当前事务id,确保事务读取到的行在事务开始前未被删除(如果事务开始之前被删除的话,删除事务id就会小于当前创建事务id,这些数据会被过滤掉),但在事务开始之后删除的数据同样也会被查询到。

简化一下就是这样子:

事务id <= 当前操作事务id && (删除id > 当前事务id || 删除id == null)

只有符合上面两个条件的数据才会被查询出来。

install操作:

增加创建版本号;

delete操作:

增加删除版本号;

update操作:

增加创建版本号;

快照读与当前读:

通过MVCC机制,虽然让数据变得可重复读,但我们读到的数据可能是历史数据,不是数据库最新的数据。这种读取历史数据的方式,我们叫它快照读,而读取数据库最新版本数据的方式,叫当前读;

对于select操作会采用快照读;
对于(install、update、delete)操作会采用当前读;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

素人岳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值