什么叫mvcc
多版本并发控制,如果只有一个事务或者单线程对数据操作的时候。
在现在主流生产环境中不可能只有一个线程对数据库操作,这个时候就需要保障数据一致性。
那么在并发情况下有哪些应用场景呢?
1.读读
不存在任何问题,不需要任何锁的添加,不需要并发控制
2.写写
可能产生丢失跟新的可能性
3.读写
并发读写怎么保证?加锁,但是效率很低————mvcc,是为了解决并发情况下读写的数据问题
前置技能:
1.当前读:
读取的永远是数据库中记录的最新数据
哪些操作会造成当前读:
1.updata
2.insert
3.delete
4.select…for updata
5.select…lock in share mode
2.快照读:
读取的不是最新的数据,而是某个历史版本的数据
那些会引起快照读:存粹的select
快照问题:要是数据库100g那么我全部都要拍下来?
每一行数据上面可以有多个版本,每一个版本是谁修改他的哪一个事务修改他的这个transaction_id一一绑定的。
所以这个100g的快照不是对100g,不是复制粘贴形成快照,而是读取的是row trxI_ID,读取到的是当前事务最新的版本号。
因为transaction_id是顺序递增的,我们把已经提交的事务ID的最大值记成up_limit_id
我们开启事务后,我们读取数据,如果我记录下来后大于up_limit_id我们就不认!
什么意思,我来们来举个例子:
1到5按顺序来执行,这里Q1,Q2的值是多少?
为什么b是20不是19??
上面说了updata触发当前读,所以读得是最新的数据
我们继续一步一步分析:
假设数据库里面最后提交的版本号为999
第一步:
先是a开启了事务,再是b开启事务,再是c开启事务,并且都记录up_limit_id=999(最大值)
第二步
事务c修改了年龄
第三步
事务b修改,updata触发快照读,直接修改数据库层面的值,拿数据库里面最新的数据
拿到的是1002号,也就是事务c的版本号,接着在这个版本号上进行修改。结果就是
事务b再去读数据的时候,因为最新修改的1001号修改的,所以拿到的是1001,正好和自己匹配,要认了所以年龄是20岁
第四步:
a事务记录的最后版本是999。1001不符合继续往上找,1002还是不符合,读到999,符合了,返回。显示18。