mysql 设置mvcc_mysql的MVCC机制

一、undo log版本链

我们在执行update,insert,delete的时候会生成undo log日志,以防止回滚使用。

一条sql执行,会生成一条undo log日志:

20200420010638434243.png

其中trx_id就是执行这条sql的事务id,roll_pointer指向对同一个值修改的undo log日志,因为当前没有,就指向一个空对象。

又有一个sql对这个数据进行修改,事务id为51,值改为B:

20200420010638633449.png

对同一条数据进行修改,通过roll_pointer连起来,就形成了undo log版本链。

二、ReadView机制

执行一个事务的时候生成一个ReadView,ReadView包括:

1.m_ids:还未提交的事务id

2.min_trx_id:m_ids中最小的事务id

3.max_trx_id:mysql生成的下一个事务id

4.creator_trx_id:当前事务id,也就是创建这个Read View的事务id

比如现在有事务A,事务B对数据进行修改,事务A生成的Read View:

20200420010638716452.png

三、mysql的RR级别实现原理

那么mysql的MVCC机制如何基于undo log版本链和ReadView来实现呢?

我们看看mysql默认的RR级别,解决了脏读、不可重复读、幻读等问题:

脏读:事务B开启,undo log生成一条日志。此时事务A来查询,值为B的这条undo log,trx_id为60,比事务A中ReadView的creator_trx_id:50要大,说明在事务A开启前执行的,查一下m_ids果然在这个集合里面,说明这个事务和事务A同时进行的,继续向下走。下一条日志的trx_id为50,就是自己事务的id可以查询,返回值A。这就解决了脏读的问题。

不可重复读:在事务B开启前,事务A查询到的值为A。提交后,事务A查询到的值还是A,解决了不可重复读的问题。

幻读:比如执行一条sql:select count(*) where id>10;

事务A刚开始查询时,满足条件的只有3条。事务B此时插入一条数据,id为6。事务A来查询,id>10的数据,发现复合查询条件的有2条,一条为原始3条,一条为事务B提交后的4条。事务A比较trx_id比事务B的小,而且在m_ids中,所以返回的是原始数据那条还是3。这就解决了幻读的问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值