首先什么是MVCC呢?
1、MVCC就是一个Mysql多版本并发控制的方法。
它是一种并发控制方法,一般在数据库管理系统中,实现数据库的并发访问,在编程语言中实现事务内存。
2、①以往最原生的锁就是,把数据锁住,然后不给多个线程去访问它,这种方式是很低效率。
②后来衍生出了读写锁,读锁和读锁之间不互斥,而写锁和写锁、读锁都互斥。这样就很大提升了系统的并发能力。之后人们发现并发读还是不够
③这时候,mvcc的概念就出现了,就是有没有一种办法,可以让读写操作不互斥呢。
3、那具体的mvcc是怎么实现的呢?--下面我们就具体讲讲这个mvcc怎么实现
①先大概讲一下他的构造,其实大概就是分为两种,快照读、当前读。
②什么是快照读,什么是当前读呢?
在讲这个之前,需要先讲我们其实每条记录都会有两个隐藏字段,分别是:
row_id:可以理解为当前事务id,因为是默认自增的,所以越大的肯定比小的是后改的
trx_id:这个叫做操作该数据事务的事务id
rool_pointer:这个隐藏其实就是指向这一条记录上一次操作的记录,指向undo日志里面。
快照读:先讲怎么形成的快照,快照就是每次做完一次事务提交之后,当前的记录都会存到一个叫undo log的文件里面。
当前读:那什么是当前读呢,当前读就是在我们insert、update、delete、以及select....for update 等的时候,读取到的数据都是当前的最新数据。
这里面也设置到一个叫做Read View的一个读视图(ids--一个事务id集合),这个视图就是在我们创建一个事务的时候,会生成的一个视图,这个视图在可重复读和读已提交的事务等级是有区别的,这个后面再讲,现在先讲一下这个Read View的用法:
①每次创建事务的时候,都会生成一个Read View,里面装的是当前数据库正在活动的事务(什么叫正在活动的事务呢?--就是说正在修改数据,但是还未提交的事务的)
例子:根据这个记录,假设,我们创建一个事务的时候,读取read view获得到的事务ids{150,255,300},当时也会读取到其他数据的事务id,然后我们就可以根据当前自己事务的id来判断我们读取到的数据是多少了:我们分几种情况分析吧:
①假设我们当前的事务id是201,那么我们先去对比read view,发现里面有一个300,这表示什么,表示我们拿到数据之后,也有另外一个事务拿到同一条数据,但是还未提交,那这时候,我们201的事务应该拿到的数据是哪个呢?这时候,我们就得去undolog文件里面根据rool_pointer找,先是找到了200,那么这个200就是已经提交的数据了,所以我们201就是拿到200的数据,也就是name为mysql。
②假设当前事务id为301,那么当我们去对比read view的时候,会发现还有一个300,也是回去undo里面找到200
△:现在这里就可以讲讲可重复读和读已提交的区别了:
当我们的隔离级别是可重复读的时候,我们的read view是不会变化的,就是比如,我们一开始读取到的read view 里面有300,即使是在这个过程里面,300的事务做了提交,我们的read view还是不会变化,
但是如果我们的隔离级别是读已提交的话,我们的read view是会做变化的。