mysql事务-MVCC

2021/06/13 1000点热度 0人点赞 0条评论

mysql事务-innodb中的redolog详解

innodb中的undolog 详解

什么是MVCC? 

使用READ COMMITTD、REPEATABLE READ 这两种隔离级别的事务执行select操作时,我们通过记录的版本链来控制事务访问相同记录时的行为,这种机制称为多版本并发控制(Multi-Version Concurrency Control).

目的:是为了提升并发访问的性能。

并发的事务在运行过程中会出现一些可能引发一致性问题的现象

  • 脏写(dirty write):一个事务修改了另一个事务未提交的数据;

  • 脏读(dirty read):一个事务读到了另一个未提交事务修改的数据;

  • 不可重复度(non-repeatable read):一个事务修改了另一个未提交事务的读取的数据;

  • 幻读(phantom):一个事务查询到数据,在未执行完之前,另一个事务又写入了一些能查询到的数据。

四种隔离级别如下:

  • READ UNCOMMITTED :读未提交,可能发生脏读、不可重复读和幻读;

  • READ COMMITTED :读已提交

  • REPEATABLE READ: 可重复读 (默认的隔离级别)

  • SERIALIZABLE :可串行化 

    图片

隔离级别的出现也是为了换取性能的提升,隔离级别越低,性能越高,越有可能发生问题。

修改隔离级别:

#sql语法
set global/session transaction isolation leavel 隔离级别;
global 表示全局范围
session:表示只是在当前会话中起作用

# 启动参数
--transaction-isolation=隔离级别

版本链

我们看下undo日志的格式和对应的版本链

图片

图片

在mysql的update和delete过程中,每对记录进行一次改动,都会记录一条undo日志,每条日志的roll_pointer都会记录innodb中最新的值,因此之前所有的改动都可以通过此属性串联。

版本链有了,但哪些版本对当前的事务可见?我们通过ReadView来控制。

ReadView

在ReadView中一共有4个比较重要的内容:

  • m_ids:生成ReadView时,当前系统中活跃的读写事务的事务id列表;

  • min_trx_id: 生成ReadView时,m_ids中最小的id值;

  • max_trx_id: 生成ReadView时,应用要分配给下一个事务的事务id;

  • creator_trx_id: 生成ReadView时,改事务的事务id;大家注意几点:

  1. 所有的属性值都是在生成ReadView时确认,也就是说ReadView是按事务隔离的;

  2. max_trx_id 为下一个事务id,因为并行时,最后一个事务id可能会先提交

此时我们再关联版本链来看下如何访问。

  • a,被访问版本的trx_id的值与ReadView中的creator_trx_id相同,表示在同一个事务中,所以这个版本可以被当前事务访问;

  • b,如果被访问版本的trx_id的值小于ReadView中的min_trx_id,表示该事务在生成ReadView前已提交,这个版本可以被访问;

  • c,如果被访问版本的trx_id大于或等于ReadView中max_trx_id,表示生成该版本的事务在生成ReadView后才生成,这个版本不可被当前事务访问;

  • d,如果被访问版本的trx_id在min_trx_id和max_trx_id之间,如果m_ids中,表示还在活跃,则不能被访问,如果不在,说明已提交,可访问。

read committed 每次读取数据前都会生成一个ReadView,这样如果一个事务中多次读取,新提交的数据也可以被读取到;repeatable read 只在第一次读取时生成一个ReadView,因为会根据上面的c和d逻辑判断,所以,新提交的数据是无法读取的。

yxkong

这个人很懒,什么都没留下

文章评论