一个 MVCC 和面试官大战30回合(上)

简介: 一个 MVCC 和面试官大战30回合(上)

文章来源我自己公众号:一个 MVCC 和面试官大战30回合

公众号很多硬核文章,求大家关注下呀~ 下面开始我们本篇文章。


我,小Y。

此刻,正坐在办公室里等待面试,心情xue微有点忐忑,不知道待会儿老面试官经不经得住我的折磨。

只见一抹光亮闪过,面试官推门而入,我抬头望去,强者的气息铺面而来,没错是那味儿。


image.png

看到面试官头上那“傲然矗立”的头发,脑海中止不住幻想他在无数个凌晨于电脑前挑灯夜码的高大形象,一种敬佩感油然而生, 竟忍不住站起来给他敬了个礼。


image.png


面试官:有病?

我:没没没,我谢顶反应综合征犯了,面试官好,我是小 Y ,请多多指教。

面试官:哦哦,确实是有病啊,没事,记得吃药就行。我看你简历写你 MySQL 挺懂的,那我先问问你 MySQL 吧。

我:好嘞,您请。

面试官:你知道什么是 MySQL 的酸吗?


image.png


这一来就这么猛的吗?脑海中一顿搜索,只能想起张含韵的我喜欢酸的甜这就是真的我之《酸酸甜甜就是我》,算了蒙一个。

我:事务?

面试官:哟,最近好多谐音梗,我特意玩了个英语单词短语梗,脑子转的挺快啊小伙子。

酸,英文 acid,说的就是事务!这都蒙对了,等下就去买彩票!趁这个机会再表现一下!

我:是啊,国外的人就有拼凑单词的习惯,其实事务主要是为了实现 C ,也就是一致性,具体是通过AID,即原子性、隔离性和持久性来达到一致性的目的,所以这四个不应该相提并论,但是他们就想拼成单词,就把它们排好序搞在一起来念。

嘿嘿,这个B装的我有点舒服,果然面试官有点惊讶。

面试官:可以呀,那你知道 MVCC 吧?

我:知道,Multi-Version  Concurrency Control (多版本并发控制)。

面试官:能先简短的解释下什么是 MVCC 吗?

我:多版本并发控制,其实指的是一条记录会有多个版本,每次修改记录都会存储这条记录被修改之前的版本,多版本之间串联起来就形成了一条版本链,这样不同时刻启动的事务可以无锁地获得不同版本的数据(普通读)。此时读(普通读)写操作不会阻塞,写操作可以继续写,无非就是多加了一个版本,历史版本记录可供已经启动的事务读取。


image.png


(为保持简短,简化了SQL语句,下文也同样简化)

面试官:那你知道事务四种隔离级别吧?

我:读未提交、读已提交、可重复读、可串行化。

面试官:MVCC 用来实现哪几个隔离级别?

我:用来实现读已提交和可重复读。首先隔离级别如果是读未提交的话,直接读最新版本的数据就行了,压根就不需要保存以前的版本。可串行化隔离级别事务都串行执行了,所以也不需要多版本,因此 MVCC 是用来实现读已提交和可重复读的。

面试官:那为什么需要 MVCC ?如果没有 MVCC 会怎样?

我:如果没有 MVCC 读写操作之间就会冲突。想象一下有一个事务1正在执行,此时一个事务2修改了记录A,还未提交,此时事务1要读取记录A,因为事务2还未提交,所以事务1无法读取最新的记录A,不然就是发生脏读的情况,所以应该读记录A被事务2修改之前的数据,但是记录A已经被事务2改了呀,所以事务1咋办?只能用锁阻塞等待事务2的提交,这种实现叫 LBCC(Lock-Based Concurrent Control)。


image.png


如果有多版本的话,就不一样了。事务2修改的记录 A,还未提交,但是记录 A 被修改之前的版本还在,此时事务1就可以读取之前的版本数据,这样读写之间就不会阻塞啦,所以说 MVCC 提高了事务的并发度,提升数据库的性能。

面试官:你对这个多版本有没有什么别的理解?

我:(面试官要开始操作我了吗?不过就这,我早有准备!)有点个人的小理解(假装谦虚)。其实这个多版本不是很准确,只是为了便于理解或者说展现出来像多版本的样子而已。

实际上 InnoDB 不会真的存储了多个版本的数据,只是借助 undolog 记录每次写操作的反向操作,所以索引上对应的记录只会有一个版本,即最新版本。只不过可以根据 undolog 中的记录反向操作得到数据的历史版本,所以看起来是多个版本。


image.png


面试官:那你能详细的说下 MVCC 是如何实现的吗?

我:您听好啦。

拿上面的 insert (1,XX)这条语句举例,成功插入之后数据页的记录上不仅存储 ID 1,name XX,还有 trx_id 和 roll_pointer 这两个隐藏字段:

  • trx_id:当前事务ID。
  • roll_pointer:指向 undo log 的指针。


image.png


从图中可以得知此时插入的事务ID是1,此时插入会生成一条 undolog ,并且记录上的 roll_pointer 会指向这条 undolog ,而这条 undolog  是一个类型为TRX_UNDO_INSERT_REC的 log,代表是 insert 生成的,里面存储了主键的长度和值(还有其他值,不提),所以 InnoDB 可以根据 undolog  里的主键的值,找到这条记录,然后把它删除来实现回滚(复原)的效果。因此可以简单地理解 undolog 里面存储的就是当前操作的反向操作,所以认为里面存了个 delete 1 就行。

此时事务1提交,然后另一个 ID 为 5 的事务再执行 update NO where id 1 这个语句,此时的记录和 undolog 就如下图所示:


image.png


没错,之前 insert 产生的 undolog 没了,insert 的事务提交了之后对应的 undolog 就回收了,因为不可能有别的事务会访问比这还要早的版本了,访问插入之前的版本?访问

个寂寞吗?

而 update 产生的 undolog 不一样,它的类型为 TRX_UNDO_UPD_EXIST_REC

此时事务 5 提交,然后另一个 ID 为 11 的事务执行update Yes where id 1 这个语句,此时的记录和 undolog 就如下图所示:


image.png

相关文章
|
4月前
|
存储 关系型数据库 文件存储
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
48 2
|
4月前
|
关系型数据库 MySQL
面试题MySQL问题之Read uncommitted隔离级别不适用MVCC如何解决
面试题MySQL问题之Read uncommitted隔离级别不适用MVCC如何解决
45 1
|
6月前
|
消息中间件 Java 关系型数据库
面试官:说说MVCC的执行原理?
面试官:说说MVCC的执行原理?
128 1
面试官:说说MVCC的执行原理?
|
存储 关系型数据库 MySQL
【MySQL面试】说说MVCC
【MySQL面试】说说MVCC
269 0
|
存储 关系型数据库 MySQL
MySQL面试精选:MVCC你还不懂就看这篇,不懂你来找我
MySQL面试精选:MVCC你还不懂就看这篇,不懂你来找我
|
SQL 存储 关系型数据库
面试突击:MVCC 和间隙锁有什么区别?
MVCC 和间隙锁是两种完全不同的机制,但它们的目的都是相同的,都是用来保证数据库并发访问的,我们先来看二者的定义。
177 0
|
算法 关系型数据库 MySQL
一个 MVCC 和面试官大战30回合(下)
一个 MVCC 和面试官大战30回合(下)
一个 MVCC 和面试官大战30回合(下)
|
存储 缓存 监控
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(下)
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(下)
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(下)
|
缓存 Java 应用服务中间件
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(中)
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(中)
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(中)
|
存储 缓存 算法
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(上)
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(上)
如果你是 JDK 设计者,如何设计线程池?我跟面试官大战了三十个回合(上)
下一篇
无影云桌面