0
点赞
收藏
分享

微信扫一扫

5_1、事务前置知识--mvcc机制

余寿 2022-03-16 阅读 95

一、MVCC概念

MVCC全称 Multi-Version Concurrency Control(多版本并发控制),指维护一个数据的多个版本,是一种乐观锁。作用是:在使用多线程并发读取数据时,使用乐观锁替代悲观锁从而提高读的性能。

MVCC的具体实现,需要依赖于数据库记录中的三个隐式字段、undo log日志、readView(读快照)。

1.1 隐藏字段

当我们创建一张表时,InnoDB还会自动的给我们添加三个隐藏字段:

在这里插入图片描述

1.2 undolog 版本链

在DML操作时,mysql会先将数据加载到内存,同时加载到undolog中,每更新一次会形成一个版本,多次更新则会形成多版本链

在这里插入图片描述

1、不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的修改,链表尾部是最早的修改;
2、(了解)当insert的时候,产生的undo log日志只在回滚时需要,所以在事务提交后,undo log日志记录会被立即删除。
3、(了解)update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

1.3 readview (读快照)

在事务中使用select查询数据时,会形成一个读快照,读快照的数据结构为:

在这里插入图片描述

二、MVCC规则

当使用“select…from…”语句时,InnoDB会生成一个读快照,然后从版本从上至下按如下规则访问:

1、 如果被访问版本的trx_id 属性值与ReadView 中的creator_trx_id 值相同, 意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
2、如果被访问版本的trx_id属性值小于ReadView 中的min_trx_id 值,表明生成该版本的事务在当前事务生成ReadView 前已经提交,所以该版本可以被当前事务访问.
3、如果被访问版本的trx_id 属性值大于ReadView 中的max_trx_id 值, 表明生成该版本的事务在当前事务生成ReadView 后才开启,所以该版本不可以被当前事务访问
4、如果被访问版本的trx_id 属性值在ReadView 的min_trx_id 和max_trx_id 之间,则需要判断trx_id 属性值是否在m_ids 列表中。
- 如果在,说明创建ReadView 时生成该版本的事务还是活跃的,该版本不可以被访问;
- 如果不在,说明创建ReadView 时生成该版本的事务已经被提交,该版本可以被访问.


如果某个版本的数据对当前事务不可见,那就顺着版本链找到下一个版本的数据,并继续执行上面的步骤来判断记录的可见性。依此类推,直到版本链中的最后一个版本。如果记录的最后一个版本也不可见,就意味着该条记录对当前事务完全不可见, 查询结果就不包含该记录。

2.1 MVCC规则举例

在这里插入图片描述

第一次快照读结果为:trx_id为2的记录

第一次快照读结果为:trx_id为3的记录

三、MVCC规则补充说明

1、使用“select…from…”语句时,不加悲观锁,而会生成一个或多个快照,因此“select…from…”语句我们也叫快照读。

相对加锁的SQL语句,我们称为当前读,当前读SQL包括:
1、INSERT...
2、DELETE...
3、UPDATE...
4、SELECT ... FOR UPDATE
5、SELECT ... FOR SHARE

2、RC隔离级别:事务中每次使用“select…from…”语句都生成一个读快照。

3、RR隔离级别:事务中仅在第一次使用“select…from…”语句都生成一个读快照,后面的“select…from…”语句都复用这个读快照。

4、RU隔离级别:读取版本链最上面的记录,不用管修改是否提交(也都不用生成读快照)。

5、串行化隔离级别:不使用MVCC乐观锁读取数据,而是给行数据、行数据间隙加了共享的悲观锁去读数据(不属于快照读,属于当前读)。

说明:
1、串行化隔离级别,仍然能够并发读,但是:读时其他事务不能改;改时其他事务不能读也不能改;(读写串行化)
2、串行化隔离级别的实现原理,不是加的表级锁,而是通过给行数据、行数据间隙加锁(共享的next-key lock锁)锁住整张表的。

6、如果“select…from…”语句不在事务中使用(例如2.1案例中2个快照读不在事务5中),依然每次生成读快照,只是:creator_trx_id 值为0,m_ids 中无5这个数字。

不在事务中的select语句执行结果:
1、RU级别:得到最新修改
2、RC/RR/串行化级别:得到最新已提交修改

,m_ids 中无5这个数字。

不在事务中的select语句执行结果:
1、RU级别:得到最新修改
2、RC/RR/串行化级别:得到最新已提交修改
举报

相关推荐

0 条评论