首先需要知道什么是 MVCC?
MVCC 多版本并发控制。MVCC就是通过数据行的多个版本管理来实现数据库的并发控制。这项技术是的InnoDB的事务隔离级别下执行一致性读 有了保证。换言之,就是为了查询一些正在被一个事务更新的行。并且可以看到他们被更新之前的值。查询在做查询的时候就不用等待 另一个事务释放锁。
MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式就是 读-写 冲突,做到即使有多写冲突时。也能做到 不加锁,非阻塞并发读,而这个读指的就是 快照读,当前读实际时一种加锁的操作,是悲观锁的实现。而MVCC本质是采用悲观锁思想的一种方式。
对应InnoDB来说,聚簇索引中的每个记录都包含了两个必要的隐藏字段:
trx_id:每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的事务id赋值给trx_id隐藏列。
roll_pointer:回滚指针,每次修改数据时,都会把旧数据放入undo log日志中,新的数据指向该旧数据,做成一个版本链,该指针字段就称为回滚指针,通过该指针可以找到修改前的数据。
四、Read View(读视图)
有了undo log日志就可以读取记录的历史版本。但是如何去欸的那个具体的版本记录?就需要用Read View记录,他解决了行的可见性问题。
RC(读已提交) 和 RR(可重复读)必须要保证读的数据 都是其他事务已经提交的数据。所以,其他事务修改数据,但是还未提交,我们不可以访问此数据。但是可以通过MVCC可以访问 对应的历史版本。核心问题:判断版本链中的那条数据 对于当前事务是 可见的。这也是 ReadView 需要解决的问题。
ReadView 就是当某一个使用MVCC机制使用快照读而形成的视图。该试图是当前所有 活跃事务id
组成一个列表的快照。(记录版本链的统计信息)
m_trx_ids:表示在生成Read View时当前系统中活跃的事务id列表。提交了的事务不在其中。
min_trx__id:活跃的事务中最小的事务id。指的版本链的末尾
max_trx_id:表示生成Read View时系统应该分配给下一个事务的id值,同样也表示系统中最大的事务id值。
creator_trx_id:表示生成该ReadView
的事务的事务id
具体ReadView的匹配规则用下来描述
解释图片中的具体数:
图片中的活跃事务(活跃事务= 读未提交的事务)有 90,100,200。
则对应的 trx_ids = (90,100,200)
min_trx_id =90,就是最小的事务号,也就是m_ids
中的最小值,则版本链的队尾数据。
max_trx_id = 201. 是因为它为系统分配下一个事务的id。当前事务id=200.下一个就是201.并不是trx_ids中的最大值。最大值+1.
creator_trx_id:由于ReadView 是由当前事务创建,当前事务=201,所以 creatoe_trx_id = 201.
接下来就是 具体的匹配兜底规则:
需要理解的是:当前事务是201,我们需要判断的是判断链条中的那些数据可以访问。(就是用 200,100,90)分别进行匹配兜底判断。
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
时生成该版本的事务已经被提交,该版本可以被访问。
文章来源:https://www.toymoban.com/news/detail-570193.html
- READ COMMITTED —— 每次读取数据前都生成一个ReadView
- REPEATABLE READ —— 在第一次读取数据时生成一个ReadView
文章来源地址https://www.toymoban.com/news/detail-570193.html
到了这里,关于面试之MySQL中的mvcc的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!