MYSQL-01 执行sql流程&redo log&binlog

116 阅读3分钟

MySQL server层与存储引擎 执行查询语句流程

  1. 建立连接,获取权限(获取长连接后更新用户权限,此时长连接权限不会刷新)。(连接器)
  2. 查询缓存,若未命中,则执行分析器(语法,词法分析),命中直接返回。mysql8.0已删除查询缓存。
  3. 进入优化器(执行计划生成,索引选择)。
  4. 进入执行器(执行引擎,返回结果)。
  5. 在存储引擎中执行查询(存储引擎提供读写接口)。

执行更新语句流程

  1. 建立连接
  2. 执行分析器
  3. 执行优化器
  4. 进入执行器
  5. 执行引擎

当然,要了解更新语句的完整流程,我们还需要了解redo log和binlog,即mysql的日志系统。

redo log

mysql在执行更新语句时,不会直接将数据写入磁盘。而是先写入redo log(内存),再由innoDB引擎在适当的时候写入磁盘。这样能提升更新效率。 innoDB的redo log大小是固定的,那么当内存满了时,则需要innoDB先完成一部分写入磁盘操作,获得部分空闲内存后,再写入内存。 因此redo log需要write pos和checkpoint两个标记来标识当前写入位置与当前擦除位置,当write pos追上checkpoint,则将数据写入磁盘,将内存写入磁盘。 有了redo log,InnoDB就可以保证数据库发生异常重启,之前提交的数据也不会丢失,这就是InnoDB的crash-safe。

binlog

redo log数据innoDB引擎,即mysql引擎层。而binlog处于mysql的server层,又叫归档日志。 binlog没有crash-safe能力。 redo log与binlog的区别主要在于以下三点:

  1. redo log时innoDB引擎特有的,binlog是Server层实现的,所有的引擎都可以用。
  2. redo log是物理日志,存储数据页的修改记录。binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给表T中ID为2的字段C加1”。
  3. redo log是循环写,空间固定会用完,会擦除写入磁盘的记录。binlog是可以追加写的。

执行update语句的完整流程。

update T set c=c+1 where ID=2
  1. 执行器找引擎取ID=2这一行。ID是主键,引擎直接用数搜索找到这一行。如果ID=2这一行所在的数据页本来就在内存中,就直接返回给执行器。否则,引擎先从磁盘中读入数据,再返回给执行器。
  2. 执行器拿到引擎给的行数据,把这个值加上1,得到新的一行数据,再调用引擎接口写入。
  3. 引擎将这行数据更新至内存中,同时将更新操作记录到redo log中,此时redo log处于prepare状态,然后告知执行器执行完成,随时可以提交事务。
  4. 执行器生成这个操作的binlog,并将binlog写入磁盘。
  5. 执行器调用引擎的事务提交接口,引擎将刚写入的redo log改为commit状态。更新完成。