MySQL中一条更新的SQL如何执行

码农编程进阶笔记

共 2835字,需浏览 6分钟

 ·

2021-10-26 08:32

MySQL 之 -- 一条更新的 SQL 如何执行,一条更新的 SQL 语句如何执行执行流程一条 SQL 的执行流程如图所示:(图片来源于网络) 如图所示:MySQL 数据库主要分为两个层级:服务层和存储引擎层服务层:server 层包括连接器、查询缓存、分析器、优化器、执行器,包括大多数 MySQL 中的核心功能所有跨存储引擎的功能也在这一层实现,包括存储过程、触发器、视图等。获取更多视频资源,微信搜索公众号:【码农编程进阶笔记】

执行流程

一条 SQL 的执行流程如图所示:(图片来源于网络)
如图所示:

MySQL 数据库主要分为两个层级:服务层和存储引擎层

  • 服务层:server 层包括连接器、查询缓存、分析器、优化器、执行器,包括大多数 MySQL 中的核心功能所有跨存储引擎的功能也在这一层实现,包括 存储过程、触发器、视图等。

  • 存储引擎层:存储引擎层包括 MySQL 常见的存储引擎,包括 MyISAM、InnoDB 和 Memory 等,最常用的是 InnoDB,也是现在 MySQL 的默认存储引擎。存储引擎也可以在创建表的时候手动指定,比如:

SQL 语句的执行过程

  • 连接器:需要 MySQL 客户端登录,需要一个 连接器 来连接用户和 MySQL 数据库,“mysql -u 用户名 -p 密码” 进行 MySQL 登录,在完成 TCP 握手 后,连接器会根据输入的用户名和密码验证登录身份。若错误 会提示 Access denied for user。若成功,MySQL 会根据权限表中的记录来判定权限。
  • 查询缓存:MySQL 在得到一个执行请求后,会首先去 查询缓存 中查找,是否执行过这条 SQL 语句,之前执行过的语句以及结果会以 key-value 对的形式,被直接放在内存中。key 是查询语句,value 是查询的结果。如果通过 key 能够查找到这条 SQL 语句,直接返回 SQL 的执行结果。若存在缓存中,就会继续后面的执行阶段。执行完成后,执行结果就会被放入查询缓存中。优点是效率高。但是查询缓存不建议使用, 因为在 MySQL 中对某张表进行了更新操作,那么所有的查询缓存就会失效,对于更新频繁的数据库来说,查询缓存的命中率很低。需要注意:在 MySQL8.0 版本,查询缓存功能就删除了,不存在查询缓存的功能了
  • 分析器: 分为词法分析和语法分析
    1). 词法分析:首先,MySQL 会根据 SQL 语句进行解析,分析器会先做 词法分析,你写的 SQL 就是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串是什么,代表什么。
    2). 语法分析:然后进行 语法分析, 根据词法分析的结果,语法分析器会根据语法规则,判断输入的这个 SQL 语句是否满足 MySQL 语法。如果 SQL 语句不正确,就提示:You have an error in your SQL suntax
  • 优化器:经过分析器分析后,SQL 就合法了,但在执行之前,还需要进行优化器的处理,优化器会判断使用了哪种索引,使用哪种连接,优化器的作用 就是确定效率最高的执行方案。
  • 执行器:在执行阶段,MySQL 首先会判断有没有执行语句的权限,若无权限,返回没有权限的错误;若有权限,就打开表继续执行。打开表时,执行器会根据标的引擎定义,去使用该引擎提供的接口,对于有索引额表,执行的逻辑类似。
    存储引擎提供数据读取和记录的接口。

更新 SQL 语句的日志记录

日志记录用到 WAL 技术,全称为 Write-Ahead-logging

关键点为:先写日志,再写磁盘

redo log

  1. redo log 是 InnoDB 引擎 中的日志模块,只有 InnoDB 中有。
  2. redo log 是物理日志,记录 “这个数据页做了什么改动”。
  3. 是固定大小的日志模块。比如可以配置为一组 4 个文件,每个文件大小是 1GB,那么这块日志就可以记录 4GB 的内容,可以理解为一个环形结构,有一个 write pos 标识当前记录的位置,一边写入一边后移,有一个 check point 记录当前要擦除的位置(当然擦除之前要写入数据文件中),也是往后推移,并且循环的。当 write pos 追上 check point 的时候表示日志已经满了, 当前需要停下来先擦除一些记录,存到数据文件中,为需要写入的日志腾出空间。获取更多视频资源,微信搜索公众号:码农编程进阶笔记
  4. 有了 redo log,InnoDB 就保证数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 Crash-safe

binlog

  1. binlog 是 server 层的日志,称之为归档日志。因为 binlog 是 server 层的那就代表所有的存储引擎都可以使用。
  2. binglog 是逻辑日志,记录的是这个语句的原始逻辑,比如 “给 ID=2 这行的 C 字段加 1”
  3. binlog 有两种模式:statement 格式是记录执行的 sql 语句,而 row 格式是记录行的内容,会记录两行数据,分别是:更新前的这行数据和更新后的这行数据。
  4. binlog 是可以追加写的日志,在日志文件写到一定大小,会切换到下一个文件记录,并不会覆盖以前的日志。

redo log 与 binlog 执行顺序,和重要的两步提交

更新流程如图所示:红色为在执行器中执行,蓝色在 InnoDB 内部执行

update 语句执行时的内部流程。

  1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。

  2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。

  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。

  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。

  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

其中 prepare 和 commit 两个阶段就是 两步提交

若在 prepare 后写入 binlog 阶段出问题,现在这条数据是 prepare 状态,然后我们恢复数据库的时候这条数据的更新操作就会回滚,不产生变更,若在 commit 出了问题,也会进行回滚,这样可以保证数据的一致性。

浏览 33
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报