Hi,你们好!我是白日梦!本文是MySQL专题的第 24 篇。web
今天我要跟你分享的MySQL话题是:“从一条update sql执行都经历什么开始,发散开一系列的问题,看看你能抗到第几问吧”面试
换一种写做风格,自导自演面试现场!感受这样仍是比较有趣的,欢迎你们订阅个人MySQL专题,公众号首发!持续更新中~
sql
欢迎关注白日梦,公众号首发!持续连载中后端
Hi同窗,据说你上一面表现的还能够,这一面要不咱继续? 缓存
嗯,好啊! 网络
好,你说一下一条update sql的执行,都经历了哪些阶段吧
多线程
我能够画一张简图,而后咱们一块儿看一下这张脑图吧
你能够花几秒看下这个图哦
嗯,你继续!
通常在咱们的后端系统中,和数据库打交道都逻辑都放在DAO层,DAO层的持久化框架中封装了:数据驱动(Driver),SQL语句通常也都是由DAO层的持久化框架发送给数据库的。
嗯,那你说的DAO层就是上图中的客户端了吧
可是我看你的简图,貌似是把数据库划分红两部分,Server层和InnoDB层。你说说看!
是的,一般你们会把数据库分层两部分,上层的Server层和下层的存储引擎层。
总的来看:Server层主要是负责和客户端创建网络链接,接受客户端传递过来的SQL、预处理、由执行器发送给储存引擎执行。
而存储引擎会和操做系统的文件系统打交道。
我在图中画的存储引擎层是InnoDB,MySQL不止这一种执行引擎,对于MySQL来讲存储引擎是可插拔的。
常见的还有什么MyISAM、NDB、Memory等等。
嗯,你说的没错!那若是我让你写一个MySQL的Server层。
你有什么思路吗?说说看!
我.....
有思路,下面我用大白话简单描述一下:
你知道的!MySQL被吹的再神,本质上不过是个软件而已,并且Server层的功能相对来讲比较简单,主要就是接受客户端的链接,拿到网络包中的SQL语句,而后处理......
而且它是单进程多线程的软件,一般会占用3306端口启动,那我彻底能够一比一写出一个MySQL Server层嘛!
好比我能够用熟悉的编程语言,TCP编程,写个TCP - Server端,监听3306端口启动。而后从接收到的数据包中取出数据,按照MySQL协议解析数据,获得SQL语句。再处理SQL语句就是了!
嗯!(我猜这家伙确定对某个数据库中间件特别熟悉)
回到正题,继续说update sql如何被处理。
好,咱们的应用程序把SQL发送给Server层后,SQL会陆续被分析器、优化器、执行器处理。
另外在图中你能看到:查询缓存。这个查询缓存由Server层维护,它设计的初衷就是在内存中暂存原来查询的结果。以便下次查询时能够快速获得结果^_^
可是它有个缺点就是当有对该表的更新操做时,该表的查询缓存会被废弃。因此MySQL8中将查询缓存砍掉了。
嗯,继续。
嗯嗯,那我继续往下说。
分析器的做用:对SQL进行语法、词法上的分析。
优化器的做用:生成执行计划、选择索引。
执行器的做用:操做执行引擎,获取SQL的执行结果。
嗯,刚才你还说你能够写个MySQL的Server层,那我如今就让你实现这个分析器!
task is cheap,show me the code!
,能够下看面的Case。
好,这个话题过
。
你继续往下说。
咱们的update sql通过server层的分析检测以后,最终由执行器交由存储引擎执行。
由于InnoDB是支持事务的,而咱们如今是update类型的SQL,因此会被放在一个单独的事务中去执行。
为了提供事务回滚的能力,因而有了上图中的第5步,InnoDB存储引擎会先写undo log。
写完undo log以后,总体的执行流程会来到图中的第6步。
在BufferPool缓存池中对内存中的数据进行update。
Buffer Pool缓存池?那我得问下
这个Buffer Pool缓存池是啥?
另外我看你上图中的Server层也有一个查询缓存呀,它和BufferPool缓存池啥区别?
嗯,是这样的。 首先咱们都知道,MySQL是支持持久化的,数据最终都落在磁盘上。
可是若是全部的update sql 都直接、大量、频繁的进行IO磁盘操做,会致使MySQL总体的性能极具降低。
如今MySQL实现方式是:它在内存中对数据进行CRUD,因此在图中能够看到,BufferPool中的数据是从磁盘上读进去的。
小伙子能够!继续说!
当update sql修改完内存中的数据后,接下来就是提交事务了。提交事务的方式通常都是两阶段提交。
也就是:
一、先写redo log(prepare)
二、写binlog
三、写redo log (commit)
这些日志后续也都会有必定的机制控制把它们持久化到磁盘中。
那你说一下redo log、bin log分别给了MySQL什么能力吧
记录binlog可使MySQL就拥有:搭建集群、数据备份、数据恢复、审计的能力啊
写redolog后MySQL就拥有了崩溃恢复的能力。
嗯,那你是怎么理解这个binlog的数据恢复和redolog的崩溃恢复的呢?
binlog 有redolog 崩溃恢复的能力嘛?
嗯~,我是这样理解的:binlog由MySQL的上层也就是Server层记录。
能够看下这张图:截自部分binlog
能够看到binlog中记录的是sql语句,记录这你对哪张表的id=xx的行作了什么样的修改。
而redolog中记录的是物理层面的概念。好比redo log中会记录你对xxx表空间的XXX数据页xxx偏移量的地方作了XXX更新。
因此说,binlog的数据恢复和redo log的崩溃恢复实际上是发生在两个层面的,彻底是两码事的!
就像是上图那样,binlog的中不是记录着SQL吗?因此能够把借助binlog的实现的数据恢复理解成回放binlog中的SQL。
而redolog的崩溃恢复指的是当MySQL出现异常Crash重启后,将内存中数据恢复成崩溃前的脏数据
嗯!了解,总体上看你的回答的还能够!
我没有问题了,你还有什么想问个人吗?
没有问题了,感谢大佬百忙抽空来给我面试!
哈哈,客气!你应该会进入下一面的。好好准备,期待你下一面优秀的表现
换一种写做风格,自导自演面试现场!感受这样仍是比较有趣的,欢迎你们订阅个人MySQL专题,公众号首发!持续更新中~