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

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
那持久性又是怎么实现的?

持久性是用来保证一旦给客户返回成功,数据就不会消失,持久存在。最简单的做法,是每次写完磁盘落地之后,再给客户返回成功。但如果每次读写数据都需要磁盘 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 分别对应一个排它锁。

感受:

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

拿到字节跳动offer后,简历被阿里捞了起来,二面迎来了P9"盘问"

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

[外链图片转存中…(img-mFFV4uw4-1714710175332)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值