【MYSQL】一条sql的执行过程

【MYSQL】一条sql的执行过程   

1、SQL接口,负责接收处理收到的SQL语句。

2、查询解析器,负责对SQL语句进行解析,让MySQL能看懂SQL语句,按照SQL语法解析出这条SQL要干啥。

3、查询优化器,选择最优的查询路径,指定执行计划(全表扫描还是走索引)

4、调用存储引擎接口真正开始执行SQL语句。

  存储引擎就是用来执行SQL的,在MySQL中,SQL接口、SQL解析器、查询优化器都是通用的,但是存储引擎不是,可以选择不同的存储引擎来执行SQL,一般用InnoDB。

  

  InnoDB存储引擎中有一个非常重要的组件叫缓冲池(buffer pool) 。如当更新一条数据时InnoDB会根据更新条件查找这条数据是否在缓冲池里,如果在就不再去磁盘加载。如果不在会从磁盘加载到缓冲池中,并对这条数据加独占锁

undo日志文件

      之后,会将更新前的这条数据记录到一个日志文件里,这个文件就是undo日志文件 。 可用于数据的回滚。

   当把要更新的数据从磁盘加载到缓冲池并对其加了独占锁之后就可以在缓冲池中对其进行修改了,修改后的数据因为还没有刷新到磁盘所以这个时候称其为脏数据

  有undo buffer的,写undo log前,会先放在内存buffer中,在刷新redo log之前写入到磁盘上的undo tablespace中。

Redo Log Buffer、redo 日志

  当缓冲池中的数据修改完之后,还没刷到磁盘。如果此时数据库宕机就会导致更新后的数据丢失。

  此时需要把修改的数据记录下来,redo日志就是记录修改后的数据的。Redo Log Buffer也是一个缓冲区,用来存储redo日志文件。可以在数据库宕机后用来恢复更新后的数据。当事务提交的时候可以选择将redo日志写入到磁盘中。(在没提交事务时就算数据丢掉了也没关系,因为事务没提交sql执行不成功)

redo日志文件刷盘策略

  当事务提交时可以通过innoDB_flush_log_at_trx_commit配置redo日志刷盘的策略。

1、当这个参数时0时,事务提交的时候不会将redo日志刷新到磁盘,这时如果宕机数据是会丢失的。

2、当这个参数是1时,事务提交时就会将redo log从内存刷入到磁盘,是要事务提交了redo log就一定在磁盘了。可以防止数据的丢失。

3、当这个参数是2时,事务提交后会将redo log写入磁盘文件对应的os cache中去,不会直接刷到磁盘,可能过了一秒才会os cache里的数据刷入到磁盘。有丢数据的风险。

所以,一般选择将innoDB_flush_log_at_trx_commit设置为1。redo log是InnoDB存储引擎特有的。

binlog

  binlog不是InnoDB特有的日志文件,而是MySQL service 自己的日志文件。 记录的也是修改后的数据。当事务提交redo log刷盘之后也会同步将binlog也刷入当磁盘中。

binlog也有自己的刷盘策略,通过sync_binlog参数配置。该参数默认是0,此时会先将binlog放到os cache中。有数据丢失的风险。当该参数配置成1时,会直接刷入到磁盘。当把binlog写入磁盘文件之后事务提交就完成了,这时会将修改对应的binlog文件名以及文件的位置都写入到redo log日志文件里,还会在redo log日志文件里写入commit标记。

 

 

commit标记

  用于判定事务是否提交成功,如果在redo log写入commit之前的任意步骤数据库宕机了都不能说事务提交成功。除此之外也用于保证redo log日志文件和binlog日志文件的一致性。

 

之后,后台IO线程会随机的将内存中的脏数据刷新到磁盘中。

 

InnoDB存储引擎主要包含了buffer pool、redo log buffer及里面的数据,还有undo日志文件、redo日志文件等。

 

 

 

 

 

 

 

  

  

    

  

posted @ 2021-11-23 18:13  99-1  阅读(72)  评论(0)    收藏  举报