MVCC概念
MVCC机制(Multi-Version Concurrency Control)主要是为了解决RC和RR级别下,读写同一份数据的并发问题。RC和RR级别下,对同一行数据的读和写默认不会通过加锁来保证隔离性,而是通过MVCC机制来保证。
undo日志版本链
undo日志版本链是由一行数据被事务修改后记录的undo回滚日志串联起来的历史记录版本链。
每一条记录,只要有写操作的事务,都会生成自己的版本链。
undo日志中,有两个隐藏字段,一个是trx_id
,记录的是修改当前记录的事务id;还有一个字段是roll_pointer
,记录的是当前记录对应的回滚指针,指向的是上一条undo日志的位置。
read view
read view是一致性视图,在RR级别,当事务开启,开始执行第一条查询语句时,就会生成read view,并且在事务结束之前不会重新生成read view;在RC级别,每一次执行查询语句的时候都会重新生成read view。
read view会保存当前未提交的事务id的数组
,以及当前已提交的事务的最大的id
。其中,未提交的事务id数组里面最小的id称为min_id
,已提交的事务最大的id称为max_id
。
RR级别和RC级别执行select语句时,mysql会根据MVCC可见性
算法查找需要的版本数据。
MVCC可见性算法
查找数据版本记录的时候,在当前记录的版本链中,从最新的版本往前查找,取满足规则的第一个版本,查找的规则如下:
- 如果当前undo日志中的trx_id小于read view中的min_id,说明这个版本是已经提交的事务生成的,那么这条数据可见
- 如果当前undo日志中的trx_id大于read view中的max_id,说明这个版本是后来的事务生成的,那么这条数据不可见
- 如果当前undo日志中的trx_id大于等于read view中的min_id,且小于等于max_id,又分为两种情况:
- 如果trx_id在未提交数组中,说明这个版本是未提交的事务生成的,那么这条数据不可见
- 如果trx_id不在未提交数据中,说明这个版本是已提交的事务生成的,那么这条数据可见
总结
MVCC机制就是通过read view和undo日志版本链进行对比,取同一条数据在版本链上的不同版本的数据。