Mysql 执行一条语句的整个过程详细

目录
  • 1.Mysql的逻辑架构
  • 2.连接器
  • 3.分析器
  • 4.优化器
  • 5.执行器
  • 6.Mysql执行一条更新语句的过程
  • 7.redo log
  • 8.bin log

1.Mysql的逻辑架构

Mysql的逻辑架构如下所示,整体分为两部分,Server层和存储引擎层。

与存储引擎无关的操作都是在Server层完成的,存储引擎层负责数据的存取。

下面将会按照上图的过程分别介绍每一步的作用,这里以查询一条记录为例。

2.连接器

这一步主要是管理连接和权限验证。

负责管理客户端的连接,比如mysql -u root -p,就是客户端与连接器之间完成的,连接分为长连接和短连接,建议使用长连接,因为建立连接是相对复杂的一个过程。但是长连接也有优化的空间,即长连接过多,随着执行大的查询操作,会占用较多的内存。

建立连接完成之后,连接器会判断该用户的权限,之后用户的操作都会基于权限来判定是否允许。

3.分析器

这一步主要是词法分析和语法分析。

词法分析主要是判定用户想做什么,比如select 就是想要查询。

语法分析主要是判定用户输入的SQL是否符合Mysql的语法。

4.优化器

经过分析器,Mysql已经知道用户想要干什么了,但是对于相同的一条SQL语句,对于Mysql具体实施的时候,可能有多种方法去实现,效率也就不一样。

在优化器这一步,mysql需要判定怎么样执行才是最优的效率。

5.执行器

这一步主要是操作引擎和返回结果。通过操作存储引擎层来遍历一张数据表,去寻找符合条件的数据,并且返回给客户端。

6.Mysql执行一条更新语句的过程

与一条SQL查询语句相同的是,在Mysql中同样要经过连接器、分析器、优化器、执行器,也要用到存储引擎来进行数据的存取。

不同的是,更新语句需要涉及到两个重要的日志模块,redo log和binlog

7.redo log

一家饭店生意红火,但作为一家饭店来说,免不了每天都有赊账和来还账的。

如果赊账和还账的人不多还好,老板可以直接用一块粉板来记录,如果人多,粉板根本写不下一个月的赊账记录。

所以老板想到可以把所有的赊账记录写到账本上,而粉板上写的都是短时间的,等下班了之后,拿粉板上的和账本进行对账。

在这个例子中,粉板就是redo log,账本就是mysql中的记录,我们用还账类比一下mysql的更新过程,如果每次有人更新,我们都去mysql中找到这条记录,效率很低,所以mysql的思路和这个老板一致,更新操作先放到redo log中,过一段时间再慢慢消化。

这种思路叫WAL技术,即Write Ahead Logging技术,先写日志,再写磁盘。

需要注意的是,粉板如果满了,老板还没下班,老板就必须停下来手中的活。mysql中的redo log总共可以记录4GB的操作

当write pos 追上check point,mysql这个老板就要去处理一下redo log了。

除此之外,有了redo log持久化,数据库即使异常重启也不会丢日志,这是crash safe机制,但仍需要注意的是,redo log是innodb存储引擎特有的。

8.bin log

binlog是Server层的日志,可以适用于所有存储引擎。

那既然有binlog了,前文为什么要搞一个innodb存储引擎专属的redo log呢?

因为mysql最开始没有innodb引擎,而是myisam引擎,使用的是binlog,但是binlog仅限于归档,没有crash safe机制,于是自己补充了一个redo log。

  • redo log是innodb存储引擎特有的,而binlog是server层特有的
  • redo log存储的是物理日志,binlog是逻辑日志
  • redo log像上面讲的那样,支持4GB大小,多了就得处理并且去覆盖,binlog日志当写满一个日志

文件之后,会新建一个新的日志文件。

下面以更新ID为2的一行数据为例:

图中浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的。

  • 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
  • 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
  • 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
  • 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

到此这篇关于Mysql 执行一条语句的整个过程详细的文章就介绍到这了,更多相关Mysql 执行一条语句的过程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解MySQL 查询语句的执行过程

    首先先简单的将一个查询语句背后MySQL做了什么捋一捋: 客户端发送一条查询给服务器. 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一个阶段. 服务器端进行SQL解析,预处理,再由优化器生成对应的执行计划. MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询. 将结果返回给客户端. 接着我们就将这个过程中的这些步骤详细的进行展开. 1.客户端和服务器端之间的通信方式 客户端和服务器之间的通信是一种半双工的通信,即在同一时刻,只能有一方向另一方发送

  • Django执行源生mysql语句实现过程解析

    1.使用extra方法 解释:结果集修改器,一种提供额外查询参数的机制 说明:依赖model模型 使用方式: 用在where后: Book.objects.filter(publisher_id="1").extra(where=["title='python学习1'"]) 用在select后 Book.objects.filter(publisher_id="1").extra(select={"count":"s

  • mysql update语句的执行过程详解

    以前有过一篇关于MySQL查询语句的执行过程,这里总结一下update语句的执行过程.由于update涉及到数据的修改,所以,很容易推断,update语句比select语句会更复杂一些. 1,准备 创建一张test表 CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `c` int(11) NOT NULL DEFAULT '0' COMMENT '数值', PRIMARY KEY (`id`) ) ENGINE=InnoDB

  • MySQL存储过程中实现执行动态SQL语句的方法

    本文实例讲述了MySQL存储过程中实现执行动态SQL语句的方法.分享给大家供大家参考.具体实现方法如下: mysql> mysql> delimiter $$ mysql> mysql> CREATE PROCEDURE set_col_value -> (in_table VARCHAR(128), -> in_column VARCHAR(128), -> in_new_value VARCHAR(1000), -> in_where VARCHAR(4

  • MySQL 存储过程中执行动态SQL语句的方法

    drop PROCEDURE if exists my_procedure; create PROCEDURE my_procedure() BEGIN declare my_sqll varchar(500); set my_sqll='select * from aa_list'; set @ms=my_sqll; PREPARE s1 from @ms; EXECUTE s1; deallocate prepare s1; end;

  • 一篇文章弄懂MySQL查询语句的执行过程

    前言 需要从数据库检索某些符合要求的数据,我们很容易写出 Select A B C FROM T WHERE ID = XX  这样的SQL,那么当我们向数据库发送这样一个请求时,数据库到底做了什么? 我们今天以MYSQL为例,揭示一下MySQL数据库的查询过程,并让大家对数据库里的一些零件有所了解. MYSQL架构 mysql架构 MySQL 主要可以分为 Server 层和存储引擎层. Server层 包括连接器.查询缓存.分析器.优化器.执行器等,所有跨存储引擎的功能都在这一层实现,比如存

  • mysql 动态执行存储过程语句

    下面写一个给大家做参考啊 复制代码 代码如下: create procedure sp_find(pfind varchar(500) BEGIN DECLAR msql varchar(2000); SET @MyQuery=Concat('select * from 表 where ',pfind); PREPARE msql from @MyQuery; EXECUTE msql; END 注意一点的就是MYSQL中有好多已经定义好的函数可以使用,比如上面的拼接函数Concat(),利用好

  • Mysql 执行一条语句的整个过程详细

    目录 1.Mysql的逻辑架构 2.连接器 3.分析器 4.优化器 5.执行器 6.Mysql执行一条更新语句的过程 7.redo log 8.bin log 1.Mysql的逻辑架构 Mysql的逻辑架构如下所示,整体分为两部分,Server层和存储引擎层. 与存储引擎无关的操作都是在Server层完成的,存储引擎层负责数据的存取. 下面将会按照上图的过程分别介绍每一步的作用,这里以查询一条记录为例. 2.连接器 这一步主要是管理连接和权限验证. 负责管理客户端的连接,比如mysql -u r

  • MySQL 常用的拼接语句汇总

    前言:在MySQL中 CONCAT ()函数用于将多个字符串连接成一个字符串,利用此函数我们可以将原来一步无法得到的sql拼接出来,在工作中也许会方便很多,下面主要介绍下几个常用的场景. 注:适用于5.7版本 低版本可能稍许不同. 1.拼接查询所有用户 SELECT DISTINCT CONCAT( 'User: \'', USER, '\'@\'', HOST, '\';' ) AS QUERY FROM mysql.USER; # 当拼接字符串中出现'时 需使用\转义符 2.拼接DROP t

  • 分析mysql中一条SQL查询语句是如何执行的

    目录 一.MySQL 逻辑架构概览 二.连接器(Connector) 三.查询缓存(Query Cache) 四.解析器(Parser) 五.优化器(Optimizer) 六.执行器 七.小结 一.MySQL 逻辑架构概览 MySQL 最重要.最与众不同的特性就是它的可插拔存储引擎架构(pluggable storage engine architecture),这种架构的设计将查询处理及其他系统任务和数据的存储/提取分离开来.来看官网的解释: The MySQL pluggable stora

  • MySQL中一条SQL查询语句是如何执行的

    目录 前言 1. 处理连接 1.1 客户端和服务端的通信方式 1.1.1 TCP/IP协议 1.1.2 UNIX域套接字 1.1.3 命名管道和共享内存 1.2 权限验证 1.3 查看MySQL连接 2. 解析与优化 2.1 查询缓存 2.2 解析器 & 预处理器(Parser & Preprocessor) 2.2.1 词法解析 2.2.2 语法分析 2.2.3 预处理器 2.3 查询优化器(Optimizer)与查询执行计划 2.3.1 什么是查询优化器? 2.3.2 优化器究竟做了什

  • Mysql使用kill命令解决死锁问题(杀死某条正在执行的sql语句)

    在使用mysql运行某些语句时,会因数据量太大而导致死锁,没有反映.这个时候,就需要kill掉某个正在消耗资源的query语句即可, KILL命令的语法格式如下: KILL [CONNECTION | QUERY] thread_id 每个与mysqld的连接都在一个独立的线程里运行,您可以使用SHOW PROCESSLIST语句查看哪些线程正在运行,并使用KILL thread_id语句终止一个线程. KILL允许自选的CONNECTION或QUERY修改符:KILL CONNECTION与不

  • PHP获取MySQL执行sql语句的查询时间方法

    如下所示: //计时开始 runtime(); //执行查询 mysql_query($sql); //计时结束. echo runtime(1); //计时函数 function runtime($mode=0) { static $t; if(!$mode) { $t = microtime(); return; } $t1 = microtime(); list($m0,$s0) = explode(" ",$t); list($m1,$s1) = explode("

  • PHP使用mysqli同时执行多条sql查询语句的实例

    PHP数据库操作中,mysqli相对于mysql有很大的优势,建议大家使用:之前我们有介绍过如何在PHP5中使用mysqli的prepare操作数据库,使用mysqli更是支持多查询特性,请看下面这段php代码: <?php $mysqli = new mysqli("localhost","root","","123456"); $mysqli->query("set names 'utf8'"

  • MyBatis一次执行多条SQL语句的操作

    有个常见的场景:删除用户的时候需要先删除用户的外键关联数据,否则会触发规则报错. 解决办法不外乎有三个: 1.多条sql分批执行: 2.存储过程或函数调用: 3.sql批量执行. 今天我要说的是MyBatis中如何一次执行多条语句(使用mysql数据库). 1.修改数据库连接参数加上allowMultiQueries=true,如: hikariConfig.security.jdbcUrl=jdbc:mysql://xx.xx.xx:3306/xxxxx?characterEncoding=u

  • 浅谈MyBatis 如何执行一条 SQL语句

    前言 Mybatis 是 Java 开发中比较常用的 ORM 框架.在日常工作中,我们都是直接通过 Spring Boot 自动配置,并直接使用,但是却不知道 Mybatis 是如何执行一条 SQL 语句的,而这篇文章就是来揭开 Mybatis 的神秘面纱. 基础组件 我们要理解 Mybatis 的执行过程,就必须先了解 Mybatis 中都有哪一些重要的类,这些类的职责都是什么? SqlSession 我们都很熟悉,它对外提供用户和数据库之间交互需要使用的方法,隐藏了底层的细节.它默认是实现类

  • mysql触发器实时检测一条语句进行备份删除思路详解

    问题描述:用户有一个这样一个需求,在一张表里会不时出现 "违规" 字样的字段,需要在出现这个字段的时候,把整行的数据删掉.这是个采集任务,如果发现有"违规"字样的数据,会整点或者什么时间进行统一上报,也无法对源头进行控制让这种数据不生成. 现在需要实现以下需求: 1.实时检测这条数据的产生,发现后删除 2.在删除之前作备份这条数据 解决思路: 需要明确解决思路, 1.首先是如何实时探测删除?询问开发,这条数据的生成方式为insert,就可以做一个当表做插入的时候,然

随机推荐