关于后端:一条-SQL-语句是如何执行的

66次阅读

共计 2345 个字符,预计需要花费 6 分钟才能阅读完成。

1. select 语句执行过程

一条 select 语句的执行过程如上图所示

1、建设连贯

连接器会校验你输出的用户名和明码是否正确,如果谬误会返回提醒,如果正确,连接器会查问以后用户对于的权限。连接器的作用就是校验用户权限

2、查问缓存

MySQL 中有个缓存的概念,当你在执行一条 SQL 查问语句时,MySQL 会先去缓存中查看是否有对应的记录,如果有,则间接返回,如果没有,则取数据库中查问,查问实现后再放入缓存中。这个查问缓存的目标是为了放慢 MySQL 查问速度。

这里倡议你将这个缓存的选项敞开上,因为在理论我的项目中,这个查问缓存用途不大,为什么这么说。因为当有 update、或者 delete 语句执行时,这张的表查问缓存就会生效,下次查问还是须要从数据库中查问,所以通常来说查问缓存并不能进步性能。

3、分析器

分析器作用是进行词法剖析,语法分析。对于 select 语句而言,MySQL 拿到这条 SQL 语句后,辨认出 select 关键词,晓得这是一条查问语句,而后再取辨认 from 以及表名,识别字段,这个步骤是词法剖析。词法剖析实现后还须要进行语法分析,也就是判断这条语句的语法是否正确,比方你 select 写成了 selct,那么语法分析就会测验进去

4、优化器

优化器职责是对 sql 语句进行优化,比方这条语句该用什么索引,sql 程序需不需要调整。

5、执行器

通过下面几部剖析,就来到了执行器,开始从数据库查问数据了。查问数据前会校验一下有无权限该表的权限,如果没有则返回谬误提醒。有权限则开始扫描行,查看是否满足条件,满足条件的后果放入后果集中。

2. update 语句执行过程

update 语句执行过程和 select 语句雷同,也须要通过连贯、分析器、优化器、执行器这些步骤。不同的是,在 update 执行过程中波及到两个日志,一个是 redo log,一个是 binlog

redo log

首先须要明确的是,redo log 是 Inndb 存储引擎独有的,其余引擎没有。redo log 次要作用是 记账

举个通俗易懂的例子,你是掌柜的,开了一家店铺,店铺生意很好,每天都有很多人来,有些人都是常客,吃饭都是月结,于是你有一个账本,账本上记录了谁欠你多少钱,店铺刚倒闭时,客人少,你一笔笔记录,没问题,起初客人多了,你发现账本查找起来很费时,影响效率,于是你找了一个黑板,客人来了当前,生产了多少钱,你就记在黑板上,等到不忙的时候在汇总到账本上。

这里的黑板就是 redo log,账本就是 MySQL 数据库磁盘,这么做的起因是为了提高效率,不然 MySQL 每一次操作都要写入到磁盘中,效率很低,有了 redo log 当前,每次 update 操作,我只须要写到内存上,而后记录到 redo log 中即可返回,这样速度快了很多。等到闲暇的时候,再将 redo log 中的数据写入到磁盘中进行长久化。

InnoDB 的 redo log 是固定大小的,比方能够配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“粉板”总共就能够记录 4GB 的操作。从头开始写,写到开端就又回到结尾循环写,如上面这个图所示。

write pos 是以后记录的地位,一边写一边后移,写到第 3 号文件开端后就回到 0 号文件结尾。checkpoint 是以后要擦除的地位,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

write pos 和 checkpoint 之间的是“粉板”上还空着的局部,能够用来记录新的操作。如果 write pos 追上 checkpoint,示意“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推动一下。

有了 redo log,InnoDB 就能够保障即便数据库产生异样重启,之前提交的记录都不会失落,这个能力称为crash-safe

要了解 crash-safe 这个概念,能够想想咱们后面赊账记录的例子。只有赊账记录记在了粉板上或写在了账本上,之后即便掌柜遗记了,比方忽然开业几天,复原生意后仍然能够通过账本和粉板上的数据明确赊账账目。

binlog

下面说的 redo log 是引擎层的日志,那么 binlog 则是 MySQL Server 层的日志

binlog 次要是记录 MySQL 的原始操作语句,比方 update user set name = “ 张三 ” where id = 2,binlog 就将它记录下来

binlog 和 redolog 区别

  • redolog 是引擎层面的日志,是 Inndb 独有的,binlog 是 Server 层的,所有引擎都能够应用
  • redo log 是物理日志,记录的是“在某个数据页上做了什么批改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比方“给 ID=2 这一行的 c 字段加 1”。
  • redo log 是循环写的,空间固定会用完;binlog 是能够追加写入的。“追加写”是指 binlog 文件写到肯定大小后会切换到下一个,并不会笼罩以前的日志。

两阶段提交

update 语句执行的外部流程

update user set name = "张三" where id = 2

  1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎间接用树搜寻找到这一行。如果 ID=2 这一行所在的数据页原本就在内存中,就间接返回给执行器;否则,须要先从磁盘读入内存,而后再返回。
  2. 执行器拿到引擎给的行数据,把这个值批改成张三
  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 外面,此时 redo log 处于 prepare 状态。而后告知执行器执行实现了,随时能够提交事务。
  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新实现。

两阶段提交就是先提交 redolog,而后写入 binlog,binlog 写入胜利后再提交 redolog

正文完
 0