如果你是路人建议先看一遍参考:MVCC多版本并发控制
看完再看我这个、我提炼是一些面试中用来回答的参考。
知道什么是当前读和快照读吗?
答:简单来说在高并发情况下当前读是获取最新的记录并且其他事务不能修改这个记录、快照读获取的有可能是老的数据。
当前读是加了锁的、加的是一种悲观锁。而快照读是没加锁的。
请你讲下MVCC是什么?
答:全称Multi-Version Concurrency Control、就是一种多并发版本控制器、通俗点就是一种并发控制的方法,一般用于数据库中对数据库的并发访问。Mysql中的innoDB中就是使用这种方法来提高读写事务控制的、他大大提高了读写事务的并发性能,原因是MVCC是一种不采用锁来控制事物的方式,是一种非堵塞、同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题。
小结一下
总之MVCC就是一些大牛、不满意读写使用锁去实现读写冲突问题、而提出的解决方案,一般在数据库中会使用MVCC加锁的方式解决读写、和写写冲突的问题。
说一下MVCC的实现原理?
答:MVCC的实现原理是依靠记录中的3个隐含字段、undo log日志、Read View来实现的。
隐含字段
有三种分别是
- 记录事务id的DB_TRX_ID、大小为6bt。
- 用来记录上一个版本数据记录的回滚指针、大小为7bt。
- 隐含的自增ID,作用是在没有设置主键的情况下自动以DB_ROW_ID产生一个簇拥索引、大小为6bt。
undo log日志
分为两种
- insert undo log:事务进行插入操作时产生、在事务回滚时需要,提交事务后可以被立即丢弃。
- update undo log:进行update、delete时产生的undo log、不仅在回滚事务时需要、在快照读时也需要。所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
purge有点像jvm中的gc垃圾回收器
实际上对MVCC有帮助的是update undo log、undo log实际就是存在rollback中的旧记录链。
Read View(读视图)
read view读视图就是在进行快照读时会产生一个read view视图、在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)。说白了就是用来记录发生快照读那一刻所有的记录,当你下次就算有执行新的事务记录改变了read view没变读出来的数据依然是不变的。
而隔离级别中的RR(可重复读)、和RC(提交读)不同就是差在快照读时
前者创建一个快照和Read View并且下次快照读时使用的还是同一个Read View所以其他事务修改数据对他是不可见的、解决了不可重复读问题。
后者则是每次快照读时都会产生新的快照和Read View、所以就会产生不可重复读问题。