Mysql数据库Innodb引擎的隔离级别、MVCC、使用锁解决幻读问题

吐槽:最近在找工作,今天着重看了一下mysql相关的东西,MVCC实现过程、以及如何解决幻读问题

一、事务隔离级别

1、读未提交(RU)   --会产生脏读

2、读已提交(RC)  --会导致不可重复读

3、可重复读(RR) --会产生幻读,mysql通过加锁解决了幻读

4、串行化(S)       --事务顺序执行,不会出现上面的这些问题,但是效率慢

话不多说,下面直接记录下MVCC的实现细节

二、MVCC(多版本并发控制)

mysql数据库mvcc只作用在RC、RR两种隔离级别下,RU和S不需要并发版本控制,mysql默认事务隔离级别是RR。

重点:实现mvcc需要两个隐藏字段,我们创建的表中都有两个隐藏字段DATA_TRX_ID(操作该数据的事务ID)和DATA_ROLL_PTR(指向undo.log的指针);undo.log是一个链表(个人理解:每个行数据都有一个自己的undo.log链表,会将当前行数据历史版本的数据一链表的形式存储起来,用于快照读和回滚操作);

mvcc中还有一个重要的东西就是Read View,里面里几个参数需要只要一下:

mIds:当前活跃的事务id集合;

min_trx_id:当前活跃的事务id集合中最小的事务id(开启每个事务所分配的事务id都是按顺序递增的,id大的一定是在id小的之后开启的);

max_trx_id:最大事务id(这里的最大事务id不是mids集合中最大的事务id,而是数据库中已经申请到最大事务id);

creator_trx_id:创建Read View的事务id(当前事务id);

事务中读取数据时会用到Read View中的参数去删选每行数据的哪个版本是可以查出来的

RC(读已提交)隔离级别下:

每次查询数据时,都需要创建一个Read View,所以如果两个查询之间有其他事务修改了某个数据并提交了,两次查询看到的数据就不一样;

例如:事务A(事务ID为10)第一次查询创建的Read View属性为mIds = [10, 12, 16], min_trx_id = 10, max_trx_id = 20; 它会查询出  行数据  上事务id比10小的版本数据或者10 - 20 中间不在mIds中已经提交的版本数据;

如果第一次查询之后事务B(事务ID为21)修改了满足你查询条件的数据,并提交了事务;

事务A再查询相同条件的数据时,它会新创建一个Read View属性为mIds = [10, 12, 16], min_trx_id = 10, max_trx_id = 21; 你查询出的数据就是事务B(事务ID为21)修改后的数据了,应为他已经提交了;

再看RR级别下

RR(可重复读)隔离级别下:

事务A(事务ID为10)第一次查询创建的Read View属性为mIds = [10, 12, 16], min_trx_id = 10, max_trx_id = 20; 它会查询出  行数据  上事务id比10小的版本数据或者10 - 20 中间并且不在mIds中已经提交的版本数据;

如果第一次查询之后事务B(事务ID为21)修改了满足你查询条件的数据,并提交了事务;

以上和RC级别下情况一样;

此时事务A再去查询相同条件的数据时,不会新建Read View,使用的还是第一次查询创建的Read View 还是mIds = [10, 12, 16], min_trx_id = 10, max_trx_id = 20; 注意看max_trx_id还是20,他就取不到事务B(事务ID为21)修改的数据;因为在他看来最大的事务Id就是20,大于20的都是未来数据。

以上是RR级别下怎么解决不可重复读的问题(使用快照读,一个事务多次读取只在第一次读的时候创建Read View);

下面说下RR级别下怎么解决幻读的问题:

RR级别下解决幻读问题需要加锁(next-key lock 临键锁),临键锁是行锁 + 间隙锁共同使用的结果;

在一个事务中如果不想查询的数据被其他事务修改,需要使用当前读语法select for update来给数据加上左开右闭的临键锁(注意:如果查询字段是唯一索引的话,临键锁为退化为行级锁),其他事务操作临键锁内的数据会被阻塞;

即锁住当前值及当前值左右的间隙(针对索引值范围的边界条件),防止其他事务插入;

有问题请大佬们指出,勿喷!!!感谢。

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值