欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MySQL之多版本并发控制(MVCC)

程序员文章站 2022-06-14 18:57:41
...
在程序员的思维里,并发控制永远都是值得讨论的话题。这里我就不过多的去讲解并发控制的基本概念了

[b]●基本概念[/b]
MVCC:Multi-Version Concurrency Control 多版本并发控制。笔者用自己的话对MVCC做一个总结:通过某个时间点上的数据快照对数据的版本控制,目的是为了避免使用各种锁影响并发性能

[b]●MySQL锁机制[/b]
说到锁,MySQL里提供了几种锁机制
[b]读写锁
表锁
行级锁[/b]
笔者不来一一解释这几种锁的基本概念了,百度谷歌应该会有不少。笔者这里需要说一点,不管使用了什么锁,锁的方式都是隐式锁定的,不需要手动去做任何事情。因为笔者曾经和人讨论MySQL锁机制的时候曾有人提出使用for update的方式锁定。这种方式实际为MySQL显示锁定,MySQL的文档里有说明此方法并不推荐使用的。实际上也并不需要使用,原因上面已经讲过了。所有的锁都是隐式锁定的
MySQL提供了两种显示锁定的方式

select * for update
select * lock in share mode

程序员们千万记住,以上的语句完全没有必要,不仅如此,还会极为浪费性能。实际上InnoDB的行级锁已经完全处理OK了

[b]●MVCC控制[/b]
基于性能考虑,实际MySQL大多的事务型存储引擎的实现都不是简单的行级锁,而是大量的使用了MVCC。
MVCC的实现,是通过数据保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据食物开始时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

不同的存储引擎的MVCC的实现方式是不同的,最典型的有乐观并发控制和悲观并发控制。

InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,一个保存了行的创建版本号,一个保存了行的过期版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事物的版本号,用来和查询到的每行记录的版本号进行比较。

下面看一下REPEATABLE READ隔离级别下,MVCC具体是如何操作的

SELECT
InnoDB 会根据一下两个条件检查每行记录
a. InnoDB至查找版本早于当前事务版本的数据行,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
b.行的删除版本要么未定义,要么大于当前事务版本号。这个可以确保事务读取到的行,在事务开始之前未被删除
只有符合以上两个条件的记录,才能返回作为查询结果

INSERT
InnoDB为新插入的每一行保存当前系统版本号作为行版本号

DELETE
InnoDB为删除的每一行保存当前系统版本号作为行删除标识。

UPDATE
InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。
相关标签: MySQL MVCC