MVCC原理快速入门

65 阅读3分钟

MVCC(Multi-Version Concurrency Control,多版本并发控制 )是MySQL等数据库中用于实现并发控制的一种技术 ,是事务隔离级别的无锁实现方式。

mvcc原理实现的2个主要组件:

undo log(回滚日志) :undo log是MVCC实现的基础。它记录了数据被修改前的版本信息。在MySQL的InnoDB存储引擎中,undo log分为插入undo log和更新undo log 。插入undo log只在事务回滚时需要,事务提交后可立即删除;而更新undo log则会被MVCC机制用于构建数据的历史版本。比如在笔记中,记录了不同事务对 balance 字段修改前的数据版本,通过 db_trx_id 标记事务ID,db_roll_ptr 指向更早的版本。

Read View(读视图)  :当一个事务执行快照读(如普通的SELECT语句,非锁定读)时,数据库会为该事务创建一个Read View。Read View中包含了当前活跃事务(未提交事务)的最小事务ID(min_trx_id)、最大事务ID(max_trx_id) 以及创建该Read View的事务ID(creator_trx_id)。

以隔离级别读已提交为例:

事务10  begin事务20  begin
#money=1000Update order set money=800 where id=1; 
 Select * from order where id=1Commit;#moneyMoney=1000
Commit; 提交事务 

 

Undo log里面:

Idmoneydb_trx_iddb_roll_ptr
1800100X2788
Idmoneydb_trx_iddb_roll_ptr
1100010X2777
Idmoneydb_trx_iddb_roll_ptr
15000null

 

而我们因为要进行查询,mysql给我们生成了一个Read View

creator_trx_idm_idsmin_trx_idmax_trx_id
2010,  2010*21
当前事务id未提交事务的集合未提交事务最小id未开始事务

判断标准: ①如果被访问的记录版本号db_trx_id等于Read-view中的creator_trx_id,说明这个事务是当前保存的。

②如果被访问的记录版本号db_trx_id小于min_trx_id,表明该版本是在事务开始之前保存进来的。

③如果被访问的记录版本号db_trx_id大于或等于max_trx_id,说明该事务是在当前事务开始之后保存进来的。

④如果被访问的记录版本号 db_trx_id 介于 min_trx_id 和 max_trx_id 之间,说明该数据版本对应的事务在当前事务开始时处于活跃(未提交)状态。在不同隔离级别下处理方式不同, 如读已提交隔离级别下,每次查询都会创建新的Read View,需要继续从undo log找合适版本;而在可重复读隔离级别下,第一次查询创建Read View后,后续查询复用该Read View,只要数据版本不满足前面三种可见情况,就从undo log获取可见版本 。  

通过上面的判断发现只有在undo log 中db_trx_id=1时,是符合判断②逻辑的。所以得出money=1000;

读未提交:无需锁无需mvcc,因为修改数据直接修改数据源,会出现脏读.

读已提交:每次查询都会创建ReadView读取数据.

重复读:同样的查询只会第一次创建ReadView读取数据.

串行化:表锁.