1.前导知识
1.1什么是MVCC
- MVCC全称 Multi-Version Concurrency Control,即
多版本并发控制,MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。 - 多版本控制:指的是一种提高并发的技术,最早的数据库系统,只有读读之间可以并发,读写、写读、写写之间都要阻塞,引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅的提高了InnoDB的并发度,在内部实现中,InnoDB是通过undo log实现的,通过undo log可以找回数据的历史版本。找回的历史版本可以提供给用户读(按照隔离级别的定义,有些读请求只能看到比较老的数据版本),也可以在回滚的时候覆盖数据页上的数据。在InnoDB内部中,会记录一个全局的活跃读写事务数组,其主要用来判断事务的可见行。
一句话概述:MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,做到非阻塞并发读。
1.2当前读与快照读
-
当前读
像select lock in share mode
(共享锁); select for update, update,delete,insert(排它锁)这些操作就是一种当前读,因为它读取的是数据的最新版本,读取时还要保证其他事务不能修改当前记录,会对记录进行加锁。 -
快照读
不加锁的select就是快照读,即不加锁的非阻塞读;(快照读的前提是隔离级别不是串行化,串行化的隔离级别下快照读会退化成当前读) 之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但是它在很多情况下避免了加锁操作,降低了开销,既然是基于多版本,所以快照读可能读到的不一定是数据的最新版本,而有可能是之前的历史版本。
说白了MVCC就是为了实现读-写不冲突,而这个读指的就是快照读,而非当前读,当前读实际上是一种加锁的操纵,是悲观锁的实现
1.3当前读和快照读与MVCC的关系
- 准确的说,MVCC多版本并发控制指的是 “维护一个数据的多个版本,使得读写操作没有冲突” 这么一个概念,仅仅是一个理想状态
- 而在MySQL中,实现这么一个MVCC理想概念,我们就需要MySQL提供具体的功能去实现,
而快照读就是MySQL为我们实现MVCC理想模型的其中一个具体非阻塞读功能,而相对而言,当前读就是一个悲观锁的具体功能实现 - 而要说的在细致一点,快照读本身也是一个抽象概念,在深入研究,MVCC模型在MySQL中的具体实现则是由
三个隐式字段,undo log,Read View等去完成的。
1.4MVCC能解决什么问题
数据库并发场景有三种,分别是:
- 读-读: 不存在任何问题,不需要并发控制
- 读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读、不可重复读、幻读等问题。
- 写-写:有线程安全问题,可能会存在更新丢失的问题,比如第一类更新丢失,第二类更新丢失。
(第一类丢失更新:事务A回滚时,将已经提交的事务B的更新数据覆盖了;第二类丢失更新:事务A提交覆盖了事务B已经提交的数据,造成事务B所做的操作丢失)
MVCC带来的好处
MVCC是一种解决写-读冲突的无锁并发控制手段,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照,所以MVCC可以为数据库解决一下问题:
- 在并发读数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写性能
- 同时还可以解决脏读、不可重复读、幻读等事务隔离问题,但不能解决更新丢失的问题。事务总

最低0.47元/天 解锁文章

4549





