前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分析MySQL执行的流程(连接、缓存、分析、优化、执行、Undo Log、Binlog、Redo Log)

分析MySQL执行的流程(连接、缓存、分析、优化、执行、Undo Log、Binlog、Redo Log)

作者头像
DannyHoo
发布2022-05-09 09:42:09
1K1
发布2022-05-09 09:42:09
举报
文章被收录于专栏:Danny的专栏Danny的专栏

熟悉MySQL的都知道MySQL服务端实现主要分为Server层和存储引擎层。Server层负责接收和管理客户端连接、管理缓存、解析SQL、优化SQL、调用存储引擎执行SQL;存储引擎层主要负责存储、查询数据。

一条查询SQL的执行过程

(图片来自于网络)

1、连接管理

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

建立连接之后会验证用户名+密码,获取权限列表,连接完成;

连接建立后,无其他动作,则此连接将处于空闲状态;若连接后客户端长时间不发送命令到服务端,连接器会自动断开(由wait_timeout控制)

2、查询缓存

之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。

MySQL 收到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。如果当前查询语句能够直接在缓存中找到 key,那么这个 value 就会被直接返回给客户端;

如果不存在缓存,就继续执行直到完成后把结果存入缓存。(MySQL8.0后取消该功能 缓存极易失效)

3、分析SQL

分析器先会做【词法分析】。查询语句是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是 什么,代表什么,比如将 select 识别为查询语句,from 之后的字符串识别为表……

然后进行【语法分析】,判断是否符合MySQL的语法,根据SQL语法生成一个数据结构(解析树)。

4、优化SQL

经过分析器,MySQL 就知道具体要做什么操作。在开始执行之前,还要先经过优化器的处理决定选择使用哪一个方案。

比如在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接 顺序。

优化器最终会把解析树变成一个查询执行计划。

5、调用存储引擎

根据表的引擎定义,执行器选择具体的存储引擎,调引擎的接口执行查询

查询到的数据放入内存中,放入结果集里.

查询完毕后,将结果集返回给客户端

6、存储引擎

根据Server层生成的执行计划,查询并返回对应数据,不同的存储引擎执行查询的实现不一样。

一条更新SQL的执行流程

更新SQL执行流程,在Server层和查询SQL差不多,也会经过连接、查询缓存、分析、优化、执行的过程。只是查询缓存阶段,查询SQL是从缓存中查询是否存在和查询sql对应的缓存,而更新SQL是删除对应表的缓存;执行阶段,查询SQL是把磁盘或存储引擎缓存中的数据查询出来,而更新SQL是把新的数据更新到存储引擎缓存和磁盘中。

假设t_user表的存储引擎为InnoDB,一条更新SQL的执行过程如下:

【执行事务阶段】

1、客户端向MySQL发送执行 update t_user set name='小王' where id=1;的命令。

2、删除 t_user 表的所有缓存(如果开启了缓存的话)。

3-4、执行器调用InnoDB存储引擎查询接口,InnoDB在t_user表中查询id=1的记录,先从 Buffer Pool 中查询,如果存在直接返回,否则去磁盘中查询(如果id为主键,就会在聚簇索引上查询数据)。

5、在对查询到的记录修改前会先把旧值写入undo page(undo log的缓存)。

6、执行器查询到记录后,把name的值改为“小王”,调InnoDB的接口把新值写入Buffer Pool中的data page,这里注意下,MySQL执行增删改查,都是直接操作 Buffer Pool,查数据都是先从 Buffer Pool 中查,修改数据时页先写入 Buffer Pool。

7、把对Buffer Pool中data page和undo page的修改记录到 Log Buffer中(redo log的缓存)。至于Log Buffer中的内容何时持久化到磁盘,有不同的策略:

(1)根据刷盘策略执行(innodb_flush_log_at_trx_commit)

代码语言:javascript
复制
默认值为1,每次提交事务都会调用write()将log buffer中的数据写入 os buffer,并调用fsync()刷到磁盘;
值为0时,每次提交事务不操作,后台线程每秒调用write()将log buffer中的数据写入 os buffer,并调用fsync()刷到磁盘;
值为2时,每次提交事务都会调用write()将log buffer中的数据写入 os buffer,后台线程每秒调用fsync()将数据从os buffer刷到磁盘;

(2)Log Buffer空间不足时

(3)正常关闭服务器时

8、为了提升性能,事务执行过程中会把update操作记录到binlog cache,具体binlog cache的内容什么时候刷盘,也有不同的策略,根据sync_binlog来设置:

代码语言:javascript
复制
默认sync_binlog=0,表示每次提交事务都只调用write()把数据写入 os buffer,不调用fsync(),由文件系统去控制刷盘,性能最好。但如果此时宕机,会丢失未调用fsync() 的binlog日志;
sync_binlog=1的时候,表示每次提交事务都会调用fsync(),安全性最高,性能最差。
sync_binlog=N(N>1)的时候,表示每次提交事务都调用write(),但累积N个事务后才调用fsync()。

【提交事务阶段】

9、客户端向MySQL发送提交事务请求。

10、根据binlog刷盘策略把 binlog cache 刷盘到binlog文件。

11、调用InnoDB存储引擎提交事务接口,修改redo log 状态为commit,此时整个事务完成。

Buffer Pool中的脏页(修改但没有刷新到磁盘的新数据、undo log)由Master Thread 或 Purge Thread 负责根据一定策略刷新到磁盘中。

转载请注明出处——胡玉洋 《根据一条Sql来分析MySQL执行的全流程(连接、分析、优化、执行、Undo Log、Binlog、Redo Log)》

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一条查询SQL的执行过程
  • 一条更新SQL的执行流程
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档