面试现场叮叮叮……面试官:“你好,我是XX面试官,请问是小龙吗?”小龙:“面试官你好,我是小龙”面试官:“好了,现在有空吗,下面开始面试。”小龙:“嗯,我准备好了。”...其他问题....面试官:“好吧,那我们就从你的简历说起吧,我想你提到你熟悉MySQL的使用?”小龙:“哈哈,不错!”面试官:“那你能告诉我MySQL的总体结构是怎样的吗?有没有学过?”小龙:“MySQL分为服务器层和存储引擎层。服务器层包括连接器、分析器、优化器和执行器。”面试官:“现在如果我执行一条SQL语句selectnamefromxl_tbwhereprimarykeyID=1,你认为MySQL底层是如何解析执行这条SQL的?”小龙:“首先,我们的客户端需要连接到服务器,连接器需要进行认证和授权。”小龙:“那么在MySQL8.0之前,如果开启了缓存,执行这条SQL,会先以这条SQL为key缓存查询,看是否有对应的值,如果有直接返回结果,MySQL8.0会综合考虑其优缺点,然后去掉缓存。面试官:“嗯,如果没有开启缓存,或者SQL映射没有结果怎么办?”小龙:“那我们正式解析这条SQL查询结果。”面试官:“能不能简单说说如何解析SQL?”小龙:“服务器肯定不会帮你把语句都执行完。首先,它会使用分析器来分析语句是否符合其语法规则。还有分析关键词等等。”小龙:“如果语法没问题,不能直接拿来执行,因为要考虑执行成本等等。”面试官:“那它内部是怎么实现的?小龙:“MySQL会通过优化器生成SQL语句的执行计划,我们可以通过explain命令进行查询。那么如果使用索引,你可能会选择索引,它会选择最优的计划执行,因为即使使用索引,在某些情况下,也可能不如全表扫描快。”小龙:"这里,我们必须使用主键索引,根据ID=1进行查找。”面试官:“恩恩,得到最优执行计划后,最后是怎么执行的?”小龙:“最后一条语句来到执行器,开表调用存储引擎接口,判断是否满足查询条件line按行。当然,如果使用索引的话,会根据索引进行过滤,速度会更快。这里是使用主键索引查询ID=1的结果。”小龙:“然后将符合条件的放入结果集中,最后返回给客户端显示。”面试官:“嗯,我理解的很清楚。OK,你知道MySQL事务的四大特性吗?”独白:“这个很基础。”小龙:“ACID、Atomicity、Isolation、Persistence、Consistency”面试官:“OK,那你知道底层是怎么实现的吗,随便挑两个说说吧?”独白:“这个在我的【面试手记】】已经总结的很详细了,随便给面试官几个吧。”小龙:“比如原子性。我们知道,原子性的关键在于事务回滚时,所有??已经执行成功的SQL语句都可以撤销。”小龙:“当事务修改数据库时,InnoDB会生成相应的undolog。undolog会保存事务开始前旧版本的数据。当事务发生异常时,会回滚到旧版本状态。”面试官:“那怎么回滚呢?”小龙:“InnoDB会根据undolog的内容做相反的逻辑操作,比如:回滚时会执行insert语句,delete和update语句,将rollingback的时候执行反之update,把数据改回来。”小龙:“简单来说,原子性主要靠undolog来保证。它是一个回滚日志,不仅可以用来保证原子性,还可以用来实现隔离MVCC。”小龙:“MYSQL的持久化是靠重做日志来保证的。可以记录事务开启后对数据所做的修改,可以crash-safe,redolog可以用来恢复数据库的异常掉电。”面试官:“你知道这里用到的一种WAL技术吗?”小龙:“MySQL使用的WAL技术全称是Write-AheadLogging。重点是先写日志,再写磁盘。”小龙:“你可以把redolog比作卸货的小推车。如果我们把每件东西都卸下来拿到仓库,岂不是浪费时间(效率低,还要找合适的存放位置)小龙:“这个时候如果有小推车,我们就把货物存放起来先放在小推车里,等推车满了再入库,岂不是大大提高了效率。”小龙:“我们在更新数据库的时候,先把更新操作记录在redolog中,等到redolog满了或者MYSQL空闲了再刷盘。”独白:“由于篇幅原因,这里就不做详细的总结了。有兴趣的可以阅读【面试手记】,里面有对经常考的相关核心重点公司的详细总结。”面试官:“好的,由于时间关系,我们就到此为止吧。你知道事务中的一些并发问题吗?”可以通过使用不同的隔离级别来控制。”面试官:“你能告诉我什么是幻读吗?”小龙:“举个简单的例子,比如事务A按照一定的条件读取数据,当按照原来的条件再次读取时,发现事务B新插入的数据称为幻读。”面试官:“然后能告诉我MySQL是怎么解决幻读的吗?还是根本没有解决,说说你的理解?独白:“由于篇幅原因,这里只做一个简单的总结。大家可以看【面试手记】,里面已经通过实验进行了详细的分析,可以帮助大家更好的理解。”友情提示:不要轻信帖子在互联网上有不同的意见。你复制我,我复制你。有一段时间,一个说RR隔离级别彻底解决了幻读,一个说没有。最好自己做实验,结果一目了然。我当时就是因为这个迷茫,百度搜的很烂,帖子满天飞,答案扑朔迷离。最后,他们干脆自己做了实验,最终得出了正确的结论,并在【采访笔记】中做了详细的记录。小龙:“RR隔离扇区还没有完全解决。对于幻读,只有快照读(使用MVCC解决幻读)或者当前读(间隙锁解决幻读)不会幻读。如果先读快照,然后进行当前读,期间在和快照读相同的条件下插入数据,当前读会再次出现幻读。当时秋季招聘网易云二面,记得很清楚我用这个问题彻底征服了面试官,从头到尾给了他一个清晰的分析,最后连我第二份的SP都拿到了,但是我拒绝了。面试官:“真的很好。”对了,能简单说说隔离级别机制的实现原理吗?”可能有的同学会说不会问这些问题,但是很多面试会反过来问你这个,只是你不知道.当时面试的时候,面试官并没有直接问这个问题,我一步一步的留下线索,让他问问题的时候跟着我擅长的知识走。因为写起来会很长文章,直接问了小龙:“readuncommitted下,可以直接读取数据,没有解决任何并发问题。”小龙:“Serializable,主要用到锁,读加共享锁,写加独占锁,串行执行来完成。”小龙:“readcommitted和repeatableread的实现原理是MVCCReadView的生成时序不同。可重复读只是在事务开始的时候生成一个ReadView,在后面使用;ReadCommitted会在每次执行前生成一个ReadView。《独白:》这里限于篇幅就不说ReadView了。重新安排并再次提出。”面试官:“好了,时间差不多了。今天就说这么多,下次再说吧。”“独白:不愧是我,大丈夫!”转载本文请联系小龙编码公众号。
