Mysql MVCC多并发版本控制

Mysql MVCC理解

先重复讲下Mysql事务隔离级别,脏读,重复读,幻读等概念

1.Mysql事务隔离级别

1.1).读未提交 | read uncommitted : 读取尚未提交的数据 :就是脏读
1.2).读已提交 | read committed:读取已经提交的数据 :可以解决脏读,存在重复读,幻读问题(RC)
1.3).不可重复度 | repeatable read:重读读取:可以解决脏读 和 不可重复读 ,存在幻读问题(RR,mysql默认隔离级别)
1.4).串行化 | serializable:可以解决 脏读 不可重复读 和 幻读—相当于锁表(效率太低,不考虑)

2.什么是脏读,重复读,幻读

2.1).脏读:一个事务读到另一个事务未提交的数据
2.2).重复读:(事务A在事务B提交前后都可以读,只是不能读事务B未提交的数据)一个事务A读数据,第一次读到结果name=z,另一个事务B将结果改成了name=s并提交事务,此时事务A再查询一次结果变成了name=s,两次读取的结果不同,发生重复读数据不一致问题。
2.3).幻读:(存在事务A,事务B,事务A不能读取与事务B相关切未提交的数据,事务B提交后都可以读)还是2.2中的例子,事务B正在修改name的值,事务A不能读取name的值,解决的重复读问题。但是如果是后来事务Binsert的,事务A查询还是会两次查询结果不同,新增了查询结果,这种叫做幻读。

3.MVCC:多版本并发控制

为甚么要使用MVCC呢?
3.1).MVCC能解决脏读,重复读,幻读的情况;
3.2).大多数事务型存储引擎实现都不是简单的行锁,基于并发性的考虑,一般会同时实现多版本并发控制(MVCC)处理读写冲突;
3.3).MVCC是乐观锁的一种实现,是通过保存数据在某一个时间点的快照实现的,写操作更新最新的版本,读操作读取旧版本;

4.MVCC原理

MVCC基于undo 日志,ReadView(快照读)完成。

4.1 undo log

4.1.1).当我们对记录做了变更操作时就会产生undo记录。当一行记录有多个修改记录,undo log 就会生成版本链,越早的操作在链的尾部。在这里插入图片描述
4.1.2).undo log 中除了表数据之外还有额外的字段事务id(trx_id)和回滚指针(roll_pointer)。

4.2 ReadView

对于使用Read Uncommitted隔离级别的事务来说,只需要读取版本链上最新版本的记录即可;对于使用Serializable隔离级别的事务来说,InnoDB使用加锁的方式来访问记录。而Read Committed和Repeatable Read隔离级别来说,都需要读取已经提交的事务所修改的记录,也就是说如果版本链中某个版本的修改没有提交,那么该版本的记录时不能被读取的。所以需要确定在Read Committed和Repeatable Read隔离级别下,版本链中哪个版本是能被当前事务读取的。于是ReadView的概念被提出以解决这个问题

  • m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。
  • min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。
  • max_trx_id:表示生成ReadView时系统中将要分配给下一个事务的id值。
  • creator_trx_id:表示生成该ReadView的事务的事务id。

4.2.1).如果被访问版本x的 trx_id 小于 m_ids 中的最小值 min_trx_id,说明生成该版本x的事务在ReadView生成之前就已经提交,如果版本x是最后提交的版本,那么该版本是可以被访问的。

4.2.2).如果被访问版本x的 trx_id 属性值在 m_ids 列表中最大值和最小值之间(包含),那就要判断m_ids是否包含trx_id,如果包含,说明当前版本x还未提交,不可访问,需要根据版本链寻找上一个版本y,重新判断版本y是否可以访问,如果不包含,说明当前版本x已经提交了,可以被访问。

4.2.3).如果被访问版本x的 trx_id 大于 m_ids 列表中的最大值 max_trx_id,说明生成该版本x事务是在生成ReadView之后才创建的,当前事务不可访问版本x。需要根据 Undo Log 链找到前一个版本,然后根据前一个版本的 DB_TRX_ID 重新判断前一个版本的可见性。

在MySQL中,Read Committed(RC)和Repeatable Read(RR)隔离级别下的区别就是它们生成ReadView的时机不同。

MVCC实现不同隔离级别
之前说到ReadView的机制只在Read Committed和Repeatable Read隔离级别下生效,所以只有这两种隔离级别才有MVCC。在Read Committed隔离级别下,每次读取数据时都会生成ReadView;而在Repeatable Read隔离级别下只会在事务首次读取数据时生成ReadView,之后的读操作都会沿用此ReadView。

参考:https://blog.csdn.net/weixin_42030357/article/details/106877489

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值