mysql知识点系列-MVCC原理

本文主要基于《高性能MySQL》

MVCC是多版本并发控制的缩写,其只在提交读和可重复读两个级别下起作用。MVCC使得大部分读操作都是非阻塞读,读写操作可以做到并行,比如:

  • 一个事务在更新,另一个事务可以正常查询,即使是被更新的记录也可以,但是不能在进行更新,因为更新锁记录了;
  • 一个事务正在查询,另一个事务可以正常的进行更新。包括查询的是全表,另一个事务也可以更新。删除也是一样。

这对提升读操作的并发性非常有帮助。
其原理是在每个记录行上增加两个隐藏列:

  • trx_id:当某条记录被修改的时候,会将该事务的id赋值给修改后记录的trx_id隐藏列;
  • roll_pointer:当记录被修改的时候,旧版本会写在undo log中,这个隐藏列就会记录指向旧版本的指针,通过它来找到之前的信息。

所有的版本都会被roll_pointer属性连接成一个链表,这个链表叫做版本链,头节点代表的当前记录最新值。
每当事务开始时,InnoDB便会创建一个ReadView,ReadView中主要包含3个比较重要的内容:

  1. m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。
  2. min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。
  3. max_trx_id:表示生成ReadView时系统中应该分配给下一个事务的id值,max_trx_id并不是m_ids中的最大值。

当有一个事务查询时,mysql从版本链上的最新记录开始遍历,将版本链中每个记录的trx_id与上面提到的三个值进行比较,以确定查询结果:

  1. 如果trx_id大于max_trx_id,说明在当前事务之后又开启了一个新事务,并且新事物对该记录做了修改,那么这个改动对当前查询事务是不可见的;
  2. 如果trx_id小于min_trx_id,说明该版本对应的事务已经提交,那么该版本记录是可见的;
  3. 如果trx_id在m_ids列表中,说明该版本对应的事务还未提交,那么该版本记录是不可见的。

提交读隔离级别下,每次查询开始时都会生成一个独立的ReadView;而可重复读在第一次读取数据时生成一个ReadView,在事务的整个生命周期中不变化。这样通过ReadView的不同,满足了两个隔离级别对提交数据的不同要求。

MySQL事务隔离级别详解及MVCC实现原理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值