目录
MVCC是什么?
Multiversion concurrency control (多版本并发控制)。对事物内正在处理的数据做多版本控制,以避免写操作的堵塞,而引发读操作的并发问题。
MVCC处理逻辑
通过在每行数据增加隐藏列(数据航的版本号、删除版本号)来标记当前数据行。如下图所示。
-
插入
-
删除
-
修改
-
查询
查询条件有两个关键规则:
1、查找的【数据行的版本号】要小于等于当前事务版本号;
2、查找的【删除行版本号】要大于当前事务版本号或者为NULL;
MVCC案例
-
案例一、执行顺序1,2,3,4,1
-
案例二、执行顺序3,4,1,2
在案例二中,出现了脏读(3,4的执行结果并没有commit的时候,1、2已经能够读到未提交数据)。MySQL如何解决这个问题呢?
那就是UndoLog!
Undo Log
指事务开始之前,在操作任何数据之前,首先将需操作的数据备份到一个地方 (Undo Log),它是为了实现事务的原子性:事务处理过程中如果出现了错误或者用户执行了 ROLLBACK语句,Mysql可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。
UndoLog在Mysql Innodb存储引擎中用来实现多版本并发控制:事务未提交之前,Undo保存了未提交之前的版本数据,Undo 中的数据可作为数据旧版本快照供其他并发事务进行快照读。
所以当我们执行普通select操作时,就是通过UndoLog进行的快照读;当需要读取当前数据时,通过锁机制来保证读取的数据无法通过其他事务进行修改,UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE都是当前读。
上例中,update和select其实操作的不是同一块数据区。update写入的是数据区,select读的是UndoLog的快照版本,所以不会出现脏读的问题,如果select有S锁,则会在获取锁之后(update未开始或者提交后)才能进行数据读取。