说说什么是 MVCC?
多版本并发控制(MVCC=Multi-Version Concurrency Control),是一种用来解决读 - 写冲突的无
锁并发控制。也就是为事务分配单向增长的时间戳,为每个修改保存一个版本。版本与事务时间戳
关联,读操作只读该事务开始前的数据库的快照(复制了一份数据)。这样在读操作不用阻塞写操
作,写操作不用阻塞读操作的同时,避免了脏读和不可重复读。
MVCC 可以为数据库解决什么问题?
在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数
据库并发读写的性能。同时还可以解决脏读、幻读、不可重复读等事务隔离问题,但不能解决更新
丢失问题(更新丢失就是多个事务对同一记录的操作,一个事务的操作覆盖了另一事务的操作)。
说说 MVCC 的实现原理
MVCC 的目的就是多版本并发控制,在数据库中的实现,就是为了解决读写冲突,它的实现原理主
要是依赖记录中的 3 个隐式字段、undo log、Read View 来实现的。
隐藏字段
- A 6-byte
DB_TRX_ID
用来标识最近一次对本行记录做修改 (insert 、update) 的事务的标识符 ,即最后一次修改本行记录的事务 id。 如果是 delete 操作, 在 InnoDB 存储引擎内部也属于一次 update 操作,即更新行中的一个特殊位 ,将行标识为己删除,并非真正删除。 - A 7-byte
DB_ROLL_PTR
回滚指针,指向该行的 undo log 。如果该行未被更新,则为空. - A 6-byte
DB_ROW_ID
如果没有设置主键且该表没有唯一非空索引时,InnoDB
会使用该 id 来生成聚簇索引.
Read View
不同的事务隔离级别中,当有事物在执行过程中修改了数据(更新版本号),在并发事务时需要判断一下版本链中的哪个版本是当前事务可见的。为此InnoDB有了ReadView的概念,使用ReadView来记录和隔离不同事务并发时此记录的哪些版本是对当前访问事物可见的。
undo log
除了用来回滚数据,还可以读取可见版本的数据。以此实现非锁定读
完整回答
面试官:你的简历上写了你了解MVCC,那么你能说说你对MVCC的理解吗?
我:对MVCC的理解,我认为可以从数据库的三个并发场景来说。
首先,是读与读的并发,也就是两个线程同时进行读操作,这种情况下,这两个读线程并不会产生任何的并发问题。
我:第二种是读和写并发,也就是一个线程进行读操作,另一个线程进行写操作。这种情况下,可能会读数据库的数据造成一些问题,比如,脏读,不可重复读,幻读。同时也造成了事务隔离性的问题,而数据库要求事务的执行是满足隔离性的。
我:第三种情况就是写和写并发。也就是两个线程都执行写操作。这种情况下会出现丢失修改问题。
我:解决上述问题,很明显我们可以通过加锁来解决,但是我们知道,加锁是需要大量的系统资源的。因此,就提出了MVCC,它是为了解决事务操作中并发安全问题的一种无锁并发控制技术。全称为Multi-Version Concurrency Control,多版本并发控制。
我:它是通过数据库记录中的隐式字段,Undo日志,Read View来实现的。
我:MVCC主要解决三个问题。第一个是读写并发阻塞问题,从而提高数据的并发处理能力。
第二个是MVCC采用的是乐观锁的方式来实现的,降低了死锁的概率。第三个是解决了一致性读的问题。也就是事务启动的时候,根据某个条件去读取到数据,直到事务结束的时候,再去执行相同的条件,还是读到同一份数据,不会发生变化。
我:而我们在使用MVCC的时候,一般是根据业务场景来选择组合搭配乐观锁或者悲观锁。
这两个组合中,MVCC中来解决读写冲突问题,乐观锁或者悲观锁用来解决写和写的冲突。从而最大程度的去提高数据库的并发性能。
我:MVCC为数据库提供了隔离性,并保证了数据一致性。