问:说一下一条update sql的执行,都经历了哪些阶段吧?

答:我可以画一张简图,然后我们一起看一下这张脑图吧
大型面试:一条update经历了什么? - 图1
**

  1. 一般在我们的后端系统中,和数据库打交道都逻辑都放在DAO层,DAO层的持久化框架中封装了:数据驱动(Driver),SQL语句一般也都是由DAO层的持久化框架发送给数据库的。
  2. 通常大家会把数据库分层两部分,上层的Server层和下层的存储引擎层。总的来看:
    1. Server层主要是负责和客户端建立网络连接,接受客户端传递过来的SQL、预处理、由执行器发送给储存引擎执行。
    2. 存储引擎会和操作系统的文件系统打交道。**图中画的存储引擎层是InnoDB,MySQL不止这一种执行引擎,对于MySQL来说存储引擎是可插拔的。常见的还有什么MyISAM、NDB、Memory等等。

插入问题:让你写一个MySQL的Server层,有什么思路吗?

答:有思路,下面我用大白话简单描述一下:你知道的!MySQL被吹的再神,本质上不过是个软件而已,而且Server层的功能相对来说比较简单,主要就是接受客户端的连接,拿到网络包中的SQL语句,然后处理……
并且它是单进程多线程的软件,通常会占用3306端口启动,那我完全可以一比一写出一个MySQL Server层嘛!
比如我可以用熟悉的编程语言,TCP编程,写个TCP - Server端,监听3306端口启动。然后从接收到的数据包中取出数据,按照MySQL协议解析数据,得到SQL语句。再处理SQL语句就是了!


  1. 我们的应用程序把SQL发送给Server层后,SQL会陆续被分析器、优化器、执行器处理。
    1. 分析器的作用:对SQL进行语法、词法上的分析。
    2. 优化器的作用:生成执行计划、选择索引。
    3. 执行器的作用:操作执行引擎,获取SQL的执行结果。
  2. 另外在图中你能看到:查询缓存。这个查询缓存由Server层维护,它设计的初衷就是在内存中暂存原来查询的结果。但是它有个缺点就是当有对该表的更新操作时,该表的查询缓存会被废弃。所以MySQL8中将查询缓存砍掉了。
  3. 我们的update sql经过server层的分析检测之后,最终由执行器交由存储引擎执行。因为InnoDB是支持事务的,而我们现在是update类型的SQL,所以会被放在一个单独的事务中去执行。为了提供事务回滚的能力,于是有了上图中的第5步,InnoDB存储引擎会先写undo log。

undo log和事务回滚

  1. 写完undo log之后,整体的执行流程会来到图中的第6步。在BufferPool缓存池中对内存中的数据进行update。

插入问题:提到Buffer Pool缓存池?那得问下这个Buffer Pool缓存池是啥?另外上图中的Server层也有一个查询缓存呀,它和BufferPool缓存池啥区别?

答: 嗯,是这样的。 首先我们都知道,MySQL是支持持久化的,数据最终都落在磁盘上。但是如果所有的update sql 都直接、大量、频繁的进行IO磁盘操作,会导致MySQL整体的性能极具下降。
在内存中CRUD就能获得最大的性能。后续再通过一定的机制将数据刷新回磁盘中。
MySQL实现方式是:它在内存中对数据进行CRUD,所以在图中可以看到,BufferPool中的数据是从磁盘上读进去的。
CURD时的Buffer Pool


  1. 当update sql修改完内存中的数据后,接下来就是提交事务了。提交事务的方式一般都是两阶段提交。也就是:
    1. 先写redo log(prepare)
    2. 写binlog
    3. 写redo log (commit)

这些日志后续也都会有一定的机制控制把它们持久化到磁盘中。事务的两阶段提交
redo log
bin log

问:那你说一下redo log、bin log分别给了MySQL什么能力吧?

答:写redolog后MySQL就拥有了崩溃恢复的能力。
记录binlog可以使MySQL就拥有:搭建集群、数据备份、数据恢复、审计的能力啊


问:嗯,那你是怎么理解这个binlog的数据恢复和redolog的崩溃恢复的呢?binlog 有redolog 崩溃恢复的能力嘛?

答:像数据表啊、行啊这都是一些只存在于逻辑上概念。我是这样理解的:
binlog由MySQL的上层也就是Server层记录。binlog中记录的是sql语句,记录这你对哪张表的id=xx的行做了什么样的修改。
而redolog中记录的是物理层面的概念。比如redo log中会记录你对xxx表空间的XXX数据页xxx偏移量的地方做了XXX更新。

所以说,binlog的数据恢复和redo log的崩溃恢复其实是发生在两个层面的,完全是两码事的!

binlog的中记录着SQL,所以可以把借助binlog的实现的数据恢复理解成回放binlog中的SQL。
而redolog的崩溃恢复指的是当MySQL出现异常Crash重启后,将内存中数据恢复成崩溃前的脏数据。