MySQL 沉浸式面试:隔离级别、锁、索引原理连环炮你扛得住吗?

那持久性又是怎么实现的?

持久性是用来保证一旦给客户返回成功,数据就不会消失,持久存在。最简单的做法,是每次写完磁盘落地之后,再给客户返回成功。但如果每次读写数据都需要磁盘 IO,效率就会很低。

为此,追求极致的 InnoDB 提供了缓冲。当向数据库写入数据时,会首先写入缓冲池,缓冲池中修改的数据会定期刷新到磁盘中,这一过程称为刷脏

如果 MySQL 宕机,那此时 Buffer Pool 中修改的数据不是丢失了吗?

Innodb 引入了 redo log 来解决这个问题。当数据修改时,会先在 redo log 记录这次操作,然后再修改缓冲池中的数据,当事务提交时,会调用 fsync 接口对 redo log 进行刷盘。

如果 MySQL 宕机,重启时可以读取 redo log 中的数据,对数据库进行恢复。由于 redo log 是 WAL 日志,也就是预写式日志,所有修改先写入日志,所以保证了数据不会因 MySQL 宕机而丢失,从而满足了持久性要求。

按你所说,redo log 也需要写磁盘,为什么不直接将数据写磁盘呢?

嗯。。。主要是有以下两方面的原因:

1.对 Buffer Pool 进行刷脏是随机 IO,因为每次修改的数据位置随机,但写 redo log 是追加操作,属于顺序 IO

2.刷脏是以数据页为单位,MySQL 默认页大小是 16KB,一个 Page 上一个小修改都要整页写入,所以积累一些数据一并写入会大大提升性能;而 redo log 中只包含真正需要写入的部分,无效 IO 比较少。

redo log 是持久性的核心,WAL 的思路也是持久化的常见解决方式,只有先落地了,才能应对后续的各种异常。

那隔离性怎么实现呢?

MySQL 能支持 Repeatable Read 这种高隔离级别,主要是MVCC 一起努力的结果。

我先说吧。事务在读取某数据的瞬间,必须先对其加行级共享锁,直到事务结束才释放;事务在更新某数据的瞬间,必须先对其加行级排他锁,直到事务结束才释放;

为了防止幻读,还会有间隙锁进行区间排它锁定。

然后是 MVCC,多版本并发控制,主要是为了实现可重复读,虽然锁也可以,但是为了更高性能考虑,使用了这种多版本快照的方式。

因为是快照,所以一个事务针对同一条 Sql 查询语句的结果,不会受其它事务影响。

索引原理

索引的底层实现是什么?

用的 B+树,它是一个 N 叉排序树,每个节点通常有多个子节点。节点种类有普通节点叶子节点。根节点可能是一个叶子节点, 也可能是个普通节点。

B+树

那 MySQL 为什么用树做索引?

一般而言,能做索引的,要么 Hash,要么树,要么就是比较特殊的跳表Hash 不支持范围查询,跳表不适合这种磁盘场景,而树支持范围查询,且多种多样,很多树适合磁盘存储。所以 MySQL 选择了树来做索引。

那你能说说为什么是 B+树,而不是平衡二叉树、红黑树或者 B-树吗?

平衡二叉树追求绝对平衡,条件比较苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。

同时,B+树优势在于每个节点能存储多个信息,这样深度比平衡二叉树会浅很多,减少数据查找的次数。

平衡二叉树

红黑树放弃了追求完全平衡,只追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。

但是红黑树多用于内部排序,即全放在内存中,而 B+树多用于外存上时,B+也被称为一个磁盘友好的数据结构。

同时,红黑树和平衡二叉树有相同缺点,即每个节点存储一个关键词,数据量大时,导致它们的深度很深,MySQL 每次读取时都会消耗大量 IO。

红黑树

那 B+树相比 B-树有什么优点呢?

哈哈,我觉得这就属于同门师兄较劲儿了。B+树非叶子节点只存储 key 值,而 B-树存储 key 值和 data 值,这样 B+树的层级更少,查询效率更高;

MySQL 进行区间访问时,由于 B+树叶子节点之间用指针相连,只需要遍历所有的叶子节点即可,而 B-树则需要中序遍历一遍。

B-树

这类选型问题其实很深,要深刻理解为什么要用 B+树、B+树有哪些竞争对手。换句话说,也就是要了解,哪些数据结构能做索引**。如果能答出哈希表、树、跳表**这三大类,就说明确实有自己的深入思考,这部分知识点学透了,也是加分项。

接下来讲讲聚簇索引和二级索引吧。

聚簇索引是主键上的索引,二级索引是非主键字段的索引。这两者相同点是都是基于 B+树实现。

区别在于,二级索引的叶子结点只存储索引本身内容,以及主键 ID,聚簇索引的叶子结点,会存储完整的行数据。在一定程度上,可以说二级索引就是主键索引的索引。

一般来说,面试官让介绍两个名词或者概念,潜台词就是要我们说清楚两者的相同点、不同点,说清楚了就过关。如果有些自己的总结性思考,比如在上面的对话中,阿柴回答出二级索引是主键索引的索引,这样就会让面试官眼前一亮。

下面讲讲 MySQL 锁的分类吧。

MySQL 从锁粒度粒度上讲,有表级锁、行级锁。从强度上讲,又分为意向共享锁、共享锁、意向排它锁和排它锁。

锁模式的兼容情况

那 select 操作会加锁吗?

对于普通 select 语句,InnoDB 不会加任何锁。但是 select 语句,也可以显示指定加锁。有两种模式,一种是 LOCK IN SHARE MODE 是加共享锁,还有 Select … for updates 是加排它锁。

什么情况下会发生死锁?

嗯。。。比如事务 A 锁住了资源 1,然后去申请资源 2,但事务 B 已经占据了资源 2,需要资源 1,谁都不退让,就死锁了。对于 MySQL,最常见的情况,就是资源 1、资源 2 分别对应一个排它锁。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

很多程序员,整天沉浸在业务代码的 CRUD 中,业务中没有大量数据做并发,缺少实战经验,对并发仅仅停留在了解,做不到精通,所以总是与大厂擦肩而过。

我把私藏的这套并发体系的笔记和思维脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。

不管是查缺补漏还是深度学习都能有非常不错的成效,需要的话记得帮忙点个赞支持一下

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。

不管是查缺补漏还是深度学习都能有非常不错的成效,需要的话记得帮忙点个赞支持一下

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值