MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种"用空间换时间"的并发策略:同一行数据在数据库里保留多个版本,让读事务与写事务互不阻塞,从而在高并发场景下既能保证隔离性,又能获得接近无锁的读性能。
1.核心思想
写操作不覆盖旧数据,而是生成新版本;
读操作根据事务开始时的快照,只访问对其可见的版本;
读写双方不使用同一把锁,实现"读不阻塞写,写不阻塞读"。
2.事务隔离级别
1.读未提交(RU):不使用MVCC,直接读最新版,可以读到其他事务未提交的数据。可能会造成脏读
2.读已提交(RC):每次select都新建Read View,只能读到其他事务提交的数据。解决脏读,但可能会造成同一个事务读取到的数据不同。
3.可重复读(RR):MYSQL默认的事务隔离级别,事务在第一次select时生成,之后复用,同一个事务内每次读取到的数据相同,解决脏读、不可重复读。
4.串行化(SERIALIZABLE):MVCC失效,退化为加读锁,事务串行执行,完全隔离。性能最低,但能保证最强一致性。
3.实现原理
隐藏字段:1.DB_ROW_ID:标记表中的每一行数据。
2.DB_TRX_ID:标记版本是谁产生的。
3.DB_ROLL_PTR:标记上一个版本在哪。
4.DELETED_BIT:标记是否已删除。
undo log:存放旧版本数据,用于回滚与快照读。
新纪录会指向旧纪录形成链表,链头是最新版本,链尾时最旧版本。
Read View:事务启动时生成的快照,决定当前事务能看到哪些版本。
MVCC在InnoDB中的实现用一句话来总结就是用隐藏字段+undo log版本链+Read View快照实现读不阻塞写,写不阻塞读的非锁定一致性读。