一天一道面试题——数据库篇2(SQL语句执行流程)

说一说一条SQL语句在MySQL中的执行流程。

组件

  • 连接器 【身份认证和权限】
    主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。
  • 查询缓存 【8.0后删除了,实际上是对语句可以查询结果进行KeyValue缓存】
  • 分析器 词法分析 语法分析
  • 优化器
    优化器的作用就是它认为的最优的执行方案去执行
  • 执行器
    调用引擎的接口,返回接口执行的结果

查询语句

执行过程:

  • 检查权限
  • 查询缓存
  • 分析词法和语法
  • 优化
  • 执行

更新语句 (update语句)

执行过程:

  • 先查询数据
  • 修改字段
  • 调用引擎API接口写入数据
    InnoDB先记录redo log,将数据写入Cache Pool,此时redo log加入prepare状态,通知执行器执行成功,随时可以提交。
  • 执行器收到通知后记录binlog 然后调用引擎接口,redo log 为提交状态
  • 更新完成

redo log 两阶段提交

最开始 MySQL 并没与 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自带的引擎是 MyISAM,但是我们知道 redo log 是 InnoDB 引擎特有的,其他存储引擎都没有,这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog 日志只能用来归档。

先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行。但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行,与原库的值不同。
先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,但是 binlog 里面已经记录了修改这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,,与原库的值不同。

崩溃恢复

  • 判断 redo log 是否完整,如果判断是完整的,就立即提交。
  • 如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log, 不完整就回滚事务。

总结

  • MySQL 主要分为 Server 层和引擎层,Server 层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog 只有 InnoDB 有。
  • 引擎层是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。
  • SQL 等执行过程分为两类,

查询类

权限校验—>查询缓存—>分析器—>优化器—>权限校验—>执行器—>引擎

更新类

权限校验—>分析器—>优化器—>权限校验—>执行器—>引擎,InnoDB采用两次写的方式

你可能感兴趣的:(一天一道面试题——数据库篇2(SQL语句执行流程))