一条SQL语句是如何执行的?

89 阅读5分钟

一条SQL语句是如何执行的?

导读:

在MySQL中,一条查询语句的执行流程经过连接器、分析器、优化器和执行器等功能模块,最终到达存储引擎。那么,一条更新语句的执行流程又是怎样的呢?本文将介绍一条SQL更新语句的执行过程,以及涉及的重要日志模块:redo log(重做日志)和binlog(归档日志)。

在MySQL中,执行一条更新语句的过程与查询语句类似,也经过连接器、分析器、优化器和执行器等模块,最后到达存储引擎。本文将介绍一条更新语句的执行流程,以及涉及的重要日志模块:redo log(重做日志)和binlog(归档日志)。

更新语句执行流程如下:

  1. 连接器:首先进行数据库连接。
  2. 清空缓存:更新操作会使与表相关的查询缓存失效,所以更新语句会清空表上的所有缓存结果。
  3. 分析器:词法和语法解析确定这是一条更新语句。
  4. 优化器:优化器决定使用ID索引来执行更新操作。
  5. 执行器:执行器负责具体执行更新操作,找到满足条件的行并进行更新。

与查询流程不同的是,更新流程还涉及两个重要的日志模块:redo log和binlog。

redo log是InnoDB引擎的日志模块,类似于酒店掌柜的粉板,用于提升更新操作的效率。当有一条记录需要更新时,InnoDB引擎首先将记录写入redo log,同时更新内存。这个更新操作在内存中完成,然后在系统比较空闲的时候,再将更新操作记录更新到磁盘中。redo log是固定大小的,循环写入,保证了即使数据库发生异常重启,之前提交的记录都不会丢失,实现了crash-safe的能力。

binlog是MySQL的Server层实现的归档日志,用于记录逻辑操作。它与redo log的区别在于:redo log是物理日志,记录的是在某个数据页上做了什么修改;而binlog是逻辑日志,记录的是语句的原始逻辑,比如“给ID=2这一行的c字段加1”。binlog可以追加写入,不会覆盖以前的日志。

在执行一条更新语句时,执行器首先从引擎获取ID=2这一行的数据,然后将值加1,并写入引擎接口,引擎将这行新数据更新到内存中,并记录更新操作到redo log中。同时,执行器生成该操作的binlog并写入磁盘。最后,执行器调用引擎的提交事务接口,引擎将redo log状态改为提交状态,更新完成。

以上就是一条SQL更新语句的执行流程,包括了连接器、分析器、优化器、执行器以及重要的日志模块:redo log和binlog。

重做日志(redo log)

在MySQL中,InnoDB引擎使用了类似的思路来提升更新效率。当有一条记录需要更新时,InnoDB引擎首先将记录写入redo log(粉板),并更新内存中的数据。这时候更新就算完成了。然后,在系统空闲时,引擎会将这个操作记录更新到磁盘中,就像掌柜在打烊后将赊账记录整理到账本中一样。

redo log是固定大小的,可以配置为一组文件,每个文件的大小通常为一些固定大小的块。当redo log写满时,MySQL会将最旧的一些日志记录刷新到磁盘,为新的日志记录腾出空间。

redo log的存在是为了保证数据的持久性和恢复能力。在数据库发生崩溃或意外断电等情况下,通过重做日志可以将未持久化到磁盘的操作进行恢复,确保数据的完整性。

归档日志(binlog)

归档日志(binlog)用于记录数据库的逻辑修改操作,包括更新语句、删除语句和插入语句等。与redo log不同的是,binlog是逻辑日志而非物理日志。它记录了对数据库的修改操作,而不是记录实际的数据修改内容。

binlog的主要作用是用于数据库的备份和主从复制。通过读取binlog,可以将数据库的修改操作应用到其他数据库实例,实现数据的复制和同步。

在更新语句执行过程中,MySQL会先将修改操作写入redo log,然后再写入binlog。因此,对于一条更新语句,它会先被记录在redo log中,以保证数据的持久性和恢复能力。然后,MySQL再将这个修改操作记录在binlog中,以便进行备份和主从复制。

综上所述,一条SQL更新语句的执行流程包括连接器、分析器、优化器、执行器以及重做日志和归档日志等模块。这些模块协同工作,确保数据的一致性、持久性和恢复能力。理解这些执行过程对于深入了解数据库的工作原理和性能优化非常重要。

参考

02 | 日志系统:一条SQL更新语句是如何执行的?-极客时间 (geekbang.org)