24 March 2020

一条sql的执行流程

select * from T where ID=10;

企业微信截图_5e3b57da-7961-4c4f-821e-bfe2f9776cbd.png

连接器

连接器负责跟客户端建立连接,获取权限,维持和管理连接

mysql -h$ip -P $port -u $user -p

客户端如果太长时间没有动静,链接器就会自动将它断开,这个时间由参数wait_timeout控制,默认8小时

如果在连接被断开后,客户端再次发送请求的话,就会收到一个错误提醒,Lost connection to MySQL server during query。这个时候如果你要继续,就需要重连,然后再执行请求,数据库里面,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。短连接则是每次执行完很少的几次处查询就断开连接,下次处查询再新建立一个。

查询缓存

连接建立完成后,可以执行 select 语句。执行逻辑就会来到第二步:查询缓存。MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。

查询缓存往往弊大于利。查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。

除非有一张静态表,很长时间才会更新一次。比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。

select SQL_CACHE * from T where ID=10

MySQL 8.0 版本直接将查询缓存的整块功能删掉了

分析器

词法+语法分析阶段

词法分析:将ssql从左到右一个字符,一个字符的输入,然后根据构词规则识别单词,生产多个token

企业微信截图_8c0526b3-35c5-4a3b-a5a8-e1f3bb3ea16a.png

语法

企业微信截图_996e1aa0-ea9c-411e-a8a0-b997cf4f5680.png

如果语法不对会收到如下提示

You have an error in your SQL syntax

如果解析器顺利生成语法树,将会将sql发送到预处理器

预处理器需要做两件事情

  • 查看sql中列名是否储存在于数据表中,再看表名是否正确
  • 对sql进行权限验证,判断sql是否有操作这个表的权限
优化器

经过分析器,mysql就知道你要做什么了。在开始执行之前,需要先经过优化器的处理

执行器

执行器将所有满足条件的行组成的记录集作为结果集返回给客户端。

修改操作

企业微信截图_bc274b9d-1a30-4478-9458-a83a5a89b063.png

crash-safe 能力

redo log 用于保证 crash-safe 能力。innodb_flush_log_at_trx_commit 这个参数设置成 1 的时候,表示每次事务的 redo log 都直接持久化到磁盘。

sync_binlog 这个参数设置成 1 的时候,表示每次事务的 binlog 都持久化到磁盘。这个参数我也建议你设置成 1,这样可以保证 MySQL 异常重启之后 binlog 不丢失。



blog comments powered by Disqus