毕业论文
您现在的位置: 版本控制 >> 版本控制优势 >> 正文 >> 正文

MySQL之InnoDB存储引擎MVCC

来源:版本控制 时间:2022/6/30
新媒体短视频运营求职招聘QQ群 http://www.jpm.cn/article-124253-1.html

这里介绍InnoDB存储引擎中如何通过MVCC多版本并发控制实现不同隔离级别下的查询

abstract.png基本原理版本链

在InnoDB存储引擎下,对于聚簇索引中的记录而言,其会含有两个必要的隐藏列:trx_id、roll_pointer。一方面,当事务对聚簇索引中的记录进行改动时,即会把该事务ID赋值给trx_id列;另一方面,每次对聚簇索引进行改动后,其会将该记录旧版本写入到undo日志当中。故roll_pointer列本质上就是一个指针,用于找到该聚簇索引改动前的版本。这样每次对记录进行改动即会形成一条相应的undo日志记录,同样地,在每条undo日志记录也会包含生成该版本时对应的事务ID信息。同时对于每个undo日志记录也有一个roll_pointer属性。使得undo日志记录之间可以形成一个链表,如下所示。可以看到,对于一条记录的多个历史版本形成了一个版本链

figure1.jpegReadView

前面已经看到通过版本链可以记录下各事务对记录的修改结果。而为了实现在不同隔离级别条件下,能够在版本链中找到合适的版本以对当前事务可见。InnoDB引入了ReadView的概念,其包含以下重要信息

「m_ids」:在生成ReadView时,当前数据库中活跃的读写事务的事务ID列表「min_trx_id」:在生成ReadView时,当前活跃的读写事务中最小的事务ID,也就是m_ids中的最小值「max_trx_id」:在生成ReadView时,系统中下一次给其他事务分配所使用的ID。这里对事务ID进行补充说明,一方面,事务ID的分配保证全局递增;另一方面,只有在对记录进行修改时(执行INSERT、DELETE、UPDATE语句)才会为该事务分配事务ID。否则对于一个只读事务而言,其事务ID使用默认值0「creator_trx_id」:生成该ReadView的事务所对应的事务ID

至此,我们就可以利用当前事务所生成的ReadView来判断版本链中某个版本的记录,是否对当前事务可见。具体地规则如下:

如果被访问版本的trx_id属性值等于ReadView中的creator_trx_id值。意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问如果被访问版本的trx_id属性值小于ReadView中的min_trx_id值。表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问如果被访问版本的trx_id属性值大于等于ReadView中的max_trx_id值。表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问如果被访问版本的trx_id属性值在ReadView的min_trx_id和max_trx_id之间。即min_trx_id≤被访问版本的trx_id属性值max_trx_id。则我们需要进一步判断被访问版本的trx_id属性值是不是在m_ids列表中。如果是,则说明创建ReadView时,生成该版本的事务还是活跃的,则该版本不可以被访问;反之,则说明创建ReadView时,生成该版本的事务已经被提交,故该版本可以被访问

在查询记录时,通过版本链确定版本的可见性。如果该版本可见则表示版本确定完毕,返回该版本的数据作为查询结果;反之,如果某个版本的数据对当前事务不可见的话,则根据版本链找到下一个版本的数据,重复使用上述的规则进行判断,依此类推。如果版本链中最后一个版本也不可见的话,则说明该条数据记录对该当前事务完全不可见,即查询结果不包含该记录

隔离级别ReadUn

转载请注明:http://www.0431gb208.com/sjszjzl/758.html