记录、理解、提升
为什么出现
在数据库并发场景中,只有读-读之间的操作才可以并发执行,读-写,写-读,写-写操作都要阻塞,这样就会导致 MySQL 的并发性能极差。而采用了 MVCC 机制后,只有写写之间相互阻塞,其他三种操作都可以并行,这样就可以提高了 MySQL 的并发性能。
所以MVCC其实是解决了并发读-写问题
原理解析
来看它的原理:主要是版本链,undo日志 ,Read View来实现的 表中的聚簇索引包含三个隐藏的列,row_id 列、事务ID列、回滚指针列
版本链
每次对记录进行改动,都会记录一条 undo 日志,每条 undo 日志也都有一个 roll_pointer 属性,可以将这些 undo 日志都连起来,串成一个链表,这个链表链接起来组成版本链
undo日志
undo log 主要用于记录数据被修改之前的日志,在表信息修改之前先会把数据拷贝到undo log里。当事务进行回滚时可以通过 undo log 里的日志进行数据还原。在MVCC中用于快照读的数据
Read View
ReadView 就是用来解决这个问题的,可以帮助我们解决事务可见性问题
事务进行快照读操作的时候就会产生 Read View,它保存了当前事务开启时所有活跃的事务列表。
通过事务当前的id与自己Read View中作比较,就可以来判断某个版本对自己是否可见
读已提交 和 可重复读 隔离级别的的一个非常大的区别就是它们生成 ReadView 的时机不同
读已提交是每次查询前会生成一个Read View,每次查询前都去更新Read View,意味着它只能读取已经已经提交的版本;而可重复读是在第一次读取数据时生成一个 ReadView,所以第二次查询的时候会直接复用之前的ReadView
- 快照读(Snapshot Read) :在可重复读(RR)隔离级别下,事务在开始时会创建一个快照,之后的读取操作都会基于这个快照。读取的是快照数据,不加锁的普通 SELECT 都属于快照读。
- 当前读(Current Read) :当前读就是读的是最新数据,而不是历史的数据,加锁的 SELECT,或者对数据进行增删改都会进行当前读。