数据库MVCC看这个肯定有收获

1、回顾

本文主要内容围绕MVCC多版本并发控制展开,通过本文你可以收获事务隔离级别的原理。知道幻读,不可重复读,可重复读等原理。以及数据库的一些底层知识。

1.1 数据库常见的一些问题

mysql数据库的innodb引擎中存在一些名词像幻读、脏读、不可重复读、隔离级别。我们现在先依次解释下这些名词。
脏读:事务A中读到了事务B尚未提交的数据(事务B可能会回滚)
不可重复读:一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。(不可重复读在读未提交和读已提交隔离级别都可能会出现)
幻读:一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。(幻读在读未提交、读已提交、可重复读隔离级别都可能会出现)
很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。

1.2 事务隔离级别

MySQL的事务隔离级别一共有四个,分别是读未提交、读已提交、可重复读以及可串行化。
MySQL的隔离级别的作用就是让事务之间互相隔离,互不影响,这样可以保证事务的一致性
隔离级别比较:可串行化>可重复读>读已提交>读未提交
隔离级别对性能的影响比较:可串行化>可重复读>读已提交>读未提交
由此看出,隔离级别越高,所需要消耗的MySQL性能越大(如事务并发严重性),为了平衡二者,一般建议设置的隔离级别为可重复读,MySQL默认的隔离级别也是可重复读。

1.3 二者关系总结

在这里插入图片描述

2 隔离级别实现原理

我们知道有锁这种东西,其实在数据库也是有锁的。数据库中的隔离级别读提交、可重复读都是通过基于乐观锁的MVCC方案实现的,而不是悲观锁。

在RC(读提交)级别中,数据的读取都是不加锁的,但是数据的写入、修改和删除是需要加锁的。
其实隔离级别主要是为了解决读问题,写问题我们后面再讨论。同时innodb中的默认隔离级别是可重复读,那么这里也就主要分析可重复读的原理。

2.1 MVCC在MySQL的InnoDB中的实现

在可重复读情况下,事务一旦开启就会对整个库生成一个快照,这个快照并不是把整个库复制一遍,这个快照需要保存的信息极少。它保存当前活跃的所有事务id(事务id是每启动一个事务都从数据库申请的一个自增的id)。然后从这个事务id中选出最大和最小的。并把这个最大+1和最小值分别定义为上界和下界。当前事务内,同一条sql在不同时刻执行时,会用当前事务的id和数据行上标记的事务id进行比较。
①凡是数据行上事务id小于下界,则认为改事务结束时,当前事务尚未开始。
②数据行上记录的事务id刚好在上下界之间,则需要判断这个事务id是否在活跃事务数组内,如果在,则认为当前事务启动时,这个数据被一个当时的活跃事务修改了。需要找回这个记录的历史记录。(怎么找回历史记录呢?mysql行上除了会保存数据内容,事务id,还会保存一个undo_log(回滚日志)。可以通过执行回滚日志拿到上一个版本的内容,并判断上一个版本的事务id是否小于下界,满足则取改版本数据返回,否则继续往回找)
③跟随上面②如果数据行上的事务id不在活跃数组内,说明操作这个数据事务id是在当前事务启动之前就已经提交的。数据可以直接使用。
④如果数据行上的事务id刚好大于上界,则这个数据肯定在当前事务之后启动的某个事物修改了。这种情况的话需要和2一样往前
总结上面的三种情况,一个事务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值