MYSQL 深入浅出系列 -MVCC 并发版本控制
一、什么是 mvcc
MVCC(Multi-Version Concurrency Control)是一种并发控制机制。
在 Mysql innodb 引擎中,就是以 mvcc 对事务并发进行控制的。
是一种基于乐观锁实现的无锁并发机制。
二、mvcc 涉及的几个概念
1.undo Log 版本链
unlog 是数据库用来存储修改前的数据日志的,当 mysql 发送事务回滚或并发冲突时,可用 undo log 进行数据恢复。
每个数据版本是通过数据表的隐藏列 trx_id 和 roll_pointer 按照事务时间先后顺序串联起来的,也就是我们说的 undo log 的版本链接。如下为一个版本链例子:
2. 快照读和当前读
快照读:普通的 select 语句
当前读:以下执行语句的读取
insert xxx
update xxx
delete xxx
select * from xxx for update
select * from xxx lock in share mode
3. ReadView
Read View(读视图):快照读用来提取版本数据的依据
RR 事务隔离级别,多个快照读直接共享同个 ReadView,所以理论多个读取的数据结果一致,解决了不可重复读问题
RC 事务隔离级别,每一次快照读都生成新 ReadView,多次快照读可能出现不一样的结果,出现不可重复读问题
在 Read View 中包含了以下 4 个主要的字段:
m_ids:当前活跃的事务编号集合。
min_trx_id:最小活跃事务编号。
max_trx_id:预分配事务编号,当前最大事务编号+1。
creator_trx_id:ReadView 创建者的事务编号。
Read View 提取数据的判断方法:遍链版本链中的最新 trx_id,按照以下判断规则,如果符合则返回当前版本数据,否则继续遍历下一条,最后全部不满足返回 NULL.
Read View 提取数据的判断规则:
trx_id==creator_trx_id:先将 Undo Log 最新数据行中的 trx_id 和 ReadView 中的 creator_trx_id 进行对比,如果他们两个值相同,则说明是在同一个事务中执行,那么直接返回当前 Undo Log 的数据行即可,如果不相等,则继续下面流程。
trx_id<min_trx_id:如果 trx_id 小于 min_trx_id,则说明在执行查询时,其他事务已经提交此行数据了,那么直接返回此行数据即可,如果大于等于,则继续下面流程。
trx_id>max_trx_id:如果 trx_id 如果大于等于 max_trx_id,则说明该行数据比当前操作执行的晚,当前行数据不可见,继续执行后续流程。
min_trx_id<=trx_id<max_trx_id:trx_id 在 min_trx_id 和 max_trx_id 之间还分为以下两种情况:
trx_id 在 m_ids 中:说明事务尚未执行完,该行数据不可被访问。
trx_id 未在 m_ids 中:说明事务已经执行完,可以返回该行数据。
三、mvcc 执行原理
1.以下面例子串通整个流程
2.生成的版本链为:
3.敲重点
RR 隔离级别下,事务 D 两次查询生成的 ReadView 为(都是公用一个 ReadView):
RC 隔离级别下,事务 D 第一次查询生成的 ReadView 为:
按照判断规则遍历,只有 trx_id=1 这个版本满足,条件所以查询结果为:李大明
RC 隔离级别下,事务 D 第二次查询生成的 ReadView 为:
按照判断规则遍历,只有 trx_id=2 这个版本就满足条件,所以查询结果为:李小明所以 RC 隔离级别下 2 次查询,返回了不一样的数据,出现了不可重复度问题
版权声明: 本文为 InfoQ 作者【俊】的原创文章。
原文链接:【http://xie.infoq.cn/article/88f87df85d529c4d1a46628eb】。文章转载请联系作者。
评论