你好,面试官 | 哈罗二面,MySQL事务与锁机制(加餐篇)

校招面试求职,大厂学习导航

**********************************

本期是【你好,面试官】系列文章的第12期,持续更新中.....。

回复"面试笔记"获取小龙秋招笔记,助力N名同学斩获大厂offer~。

《你好,面试官》系列目前已经连载12篇了,据说看了这个系列的朋友都拿到了大厂offer~


小龙有话说

本期会通过面试模拟探讨MySQL 高级,关于MySQL 事务实现原理锁机制undo log原理

本期题改编自 ——2022届秋招 哈罗 二面

面试现场

叮叮叮......

面试官:“你好,我是XX面试官,请问是小龙吗?”

小龙:“您好,面试官,我是小龙”

面试官:“好的,现在有空吗,我们开始面试吧”

小龙:“嗯嗯,准备好啦”

.......

other questions

.......

面试官:“我看你简历写熟悉 MySQL 使用,能给我讲讲何为事务吗?”

小龙:“用我的话来理解,就是一系列操作,要么全部成功,要么全部失败。”

面试官:“好的,那你知道事务有哪几个重要的特性吗?”

独白:“送分题来了”

小龙:”就是 ACID 嘛,原子性、隔离性、持久性、一致性啊。“

面试官:”好的,那你知道事务的隔离级别有哪些吗?“

小龙:”读未提交,读已提交、可重复读、可串行化嘛“

独白:“现在面试都那么简单的吗?那不是稳的一批。”

面试官:”能给我讲讲RC、RR吗,它们分别解决了什么问题,然后具体底层是怎样去做的呢?“

独白:“这块涉及到的一连串延展问题,在【面试笔记】做了详细分析,幻读、锁机制、事务实现原理等。”

小龙:”对于RC,它解决了脏读,具体怎样实现的呢?如果是一致读取,它是利用 MVCC 实现的,每一句语句执行前都会生成Read View(一致性视图),读取的是最新快照。“

小龙:”如果是锁定读,InnoDB 只锁定索引记录,而不是它们之前的间隙,因为该隔离级别下间隙锁被禁用,仅用于外键约束检查和重复键检查。“

小龙:”对于RR,它解决了脏读、不可重复读,它又是怎么实现的呢?对于快照读,读取第一次读取建立的快照,利用 MVCC,只有事务开始时会创建 Read View,之后事务里的其他查询都用这个Read View。“

小龙:“若是当前读,由于该级别下间隙锁生效,因此可以用临键锁来解决幻读。”

面试官:”好的,刚才我听你提了锁相关的内容,你能给我讲讲关于 MySQL 里面的锁机制吗?“

小龙:” MySQL 里面的锁有很多种,不过本质都差不多,具体要看你怎么去分吧。“

面试官:”说说看呢~。“

小龙:”如果按照锁粒度来区分的话,可分为 表级锁、行级锁、页级锁这些。如果按 锁模式 划分,又可分为 共享锁-读锁-S锁、排它锁-写锁-X锁 这些。“

小龙:”如果按加锁方式划分,又可分为自动锁、隐式锁这些,按操作划分,可分为DML锁、DDL锁等等。“

独白:"这里详细的划分与解释由于篇幅有限就不具体展开啦,【面试笔记】有详细记录。"

面试官:”好的,能说说 InnoDB 里面行锁的几种实现算法吗?“

小龙:”嗯,有记录锁( Record lock)、间隙锁(Gap lock)、临键锁(Next-key lock)。“

面试官:”好的,能分别讲讲它们们?比如有什么区别,什么作用? “

小龙:”首先说记录锁,它总是锁定索引记录,即使定义的表没有索引, InnoDB 也会创建一个隐藏的聚集索引并将该索引用于记录锁定,关于隐藏字段也是实现 MVCC 的关键。“

小龙:”锁定一个范围,不包括记录本身,由于可以锁定间隙不让插入,所以这是解决我们幻读问题的基础,需要注意的是,在某些情况间隙锁会失效。“

小龙:”比如在 RC 隔离级别下,因此 RC 是无法解决幻读问题的。又或者我们可以启用 innodb_locks_unsafe_for_binlog 系统变量,也可以显示的禁用间隙锁。“

小龙:”关于临键锁,它也锁定一个范围,但是包含记录本身,可以说它是由索引记录锁+间隙锁构成的,锁定范围前开后闭,可以以此解决 Phantom Problem 幻读问题。“

独白:”还有一些关于锁机制的规则,比如 间隙锁 何时失效,何时才有效,索引和SQL写得有问题也会导致间隙锁失效,都记录在【面试笔记】,这里不一一单独列出来了。“

面试官:”好的,之前一直听你说 快照读当前读,能说说这究竟是什么吗?“

小龙:”所谓的 快照读其实就是我们的普通查询,比如 select .... from ,而当前读也就是我们的加锁读,它读到的都是最新的数据,因此被叫做当前读,比如 select ... from for updateselect ... from lock in share modeDELETE/ UPDATE/ INSERT。“

面试官:“OK,我看你之前一直有提 MVCC,能简单讲讲这是什么吗?”

小龙:“MVCC,全称 Multi-Version Concurrency Control,即多版本并发控制,主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。”

小龙:“它主要依靠3个隐式字段undo日志Read View实现的。”

面试官:“好的,具体是怎样的呢?知道吗?”

小龙:“每行记录除了我们自定义的字段外,还有数据库隐式定义的db_trx_id,db_roll_ptr,db_row_id等字段。”

小龙:“具体代表什么呢?”

小龙:“Innodb 采用主键索引(聚簇索引),会利用主键维护索引,若表没有主键,就用第一个非空唯一索引,若没有唯一索引,则用row_id 这个隐藏字段作为主键索引。”

小龙:“然后事务开启会向系统申请一个 trx_id,严格递增,会向行记录插入最近操作它的那个事务的ID。”

小龙:“undo log 会记录事务前的老版本数据,然后行记录中回滚指针会指向老版本位置,如此形成一条版本链。因此可以利用undo log实现回滚,保证原子性,同时用于实现 MVCC 版本链。”

面试官:“它是怎样控制隔离级别的呢?”

小龙:“而在读已提交隔离级别下,会在每次查询都生成一个Read View,可重复读只在事务开始时生成一个Read View,以后每次查询都用这个Read View,以此实现不同隔离界别。”

小龙:“而这个 Read View 包含了,事务启动时当前活跃事务ID(未提交事务),和一个低水位(活跃事务最小ID),和高水位(下一次将分配的事务ID,也就是目前最大事务ID+1)”

小龙:“数据版本的可见性规则,就是基于数据的 trx_id和这个一致性视图(Read View)的对比结果得到的。”

独白:“具体详细图解+如何比对的可以都总结在【面试笔记】,篇幅有限,不具体展开了。”

面试官:“好的,既然这里我们都谈到了undo log,那你知道这是什么吗?”

小龙:“undo log是特别重要的一种回滚日志,即是 MVCC 实现的基础,也是保证原子性、事务回滚的基础。”

小龙:“关于 MVCC 的实现上面提过了,就是根据用 undo log 生成的版本链去实现。然后它还有个重要功能就是去实现原子性。”

小龙:“我们都知道,实现原子性的关键,是事务回滚时能够撤销所有已经执行成功的 SQL 语句。”

小龙:“当事务对数据库进行修改时,InnoDB 会生成对应的undo log,undo log 会保存事务开始前老版本的数据,当事务发生异常,便会 rollback 回滚到老版本状态。当发生回滚时,InnoDB 会根据 undo log 的内容做相反逻辑操作。”

面试官:“那具体是怎样回滚的呢?”

独白:“幸好在【面试笔记】详细总结过。这里大概给它讲讲算了。”

小龙:“ Insert 语句,回滚时会执行 Delete; Update语句,回滚时便执行相反的 Update,把数据改回来;Delete语句,会执行Insert,把删除的再插入回来。 ”

面试官:“好的,基础不错。继续加油~”

独白:“不愧是我,真男人是也!【面试笔记】在手,大厂 offer 不愁。”

知识总结

本期我们通过面试模拟。订阅+星标持续追更。

面试重点

MySQL事务相关undo log锁机制MVCC实现原理

#面试复盘##面经##哈啰出行#
全部评论
面试笔记,求面试笔记
点赞 回复 分享
发布于 2022-03-27 20:51

相关推荐

专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
3 13 评论
分享
牛客网
牛客企业服务