一、MVCC的简介
MySQL的MVCC(Multi-Version Concurrency Control)是一种多版本并发控制机制,用于控制事务的并发访问,一般用于数据库中对数据的并发访问。Mysql中的innoDB中就是使用这种方法来提高读写事务的并发性能、原因是MVCC是一种不采用锁来控制事务的方式,是一种非堵塞、同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题。
总之:就是MVCC是通过保存数据的历史版本,根据比较版本号来处理数据是否显示,从而达到读取数据的时候不需要加锁就可以保证事务隔离性的效果。
二、当前读和快照读
在高并发情况下,当前读是获取最新记录,并且不允许其他事务修改这个数据。
当前读是加了锁的、加的是一种悲观锁。而快照读是没加锁的。
快照读获取的则是单纯的 SELECT 语句,取的有可能是事务未提交的数据。
三、MVCC的实现原理
MVCC的实现原理是依靠:记录中的3个隐含字段、undo log日志、Read View实现的。
1、对于 InnoDB ,聚簇索引记录中包含 3 个隐藏的列:
- ROW ID:隐藏的自增 ID,如果表没有主键,InnoDB 会自动按 ROW ID 产生一个聚集索引树。
- 事务 ID:记录最后一次修改该记录的事务 ID。
- 回滚指针:指向这条记录的上一个版本。
2、undo log日志:
insert undo log:事务进行插入操作时产生、在事务回滚时需要,提交事务后可以被立即丢
update undo log:进行update、delete时产生的undo log、不仅在回滚事务时需要、在快照读时也需要。所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除(purge类似jvm中的gc垃圾回收器)
3、Read View(读视图)
read view读视图就是在进行快照读时会产生一个read view视图、在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)。
判断是否可读
- 小于最小活动事务ID,可读。
- 大于最大活动事务ID,可读。
- 之间,在集合中,不可读,不在集合中,可读。
ReadView生成时机
- READ COMMITTED —— 每次读取数据前都生成一个ReadView。
- REPEATABLE READ —— 在第一次读取数据时生成一个ReadView。
4:总结出 MVCC 实现的原理大致是:
InnoDB 每一行数据都有一个指向上一个版本数据在undo log日志里的位置指针。如果要执行更新操作,会将原记录放入 undo log 中,并通过隐藏的回滚指针指向 undo log 中的原记录。其它事务此时需要查询时,就是查询 undo log 中这行数据的最后一个历史版本。
MVCC 最大的好处是读不加锁,读写不冲突,极大地增加了 MySQL 的并发性。通过 MVCC,保证了事务的隔离性。