Mysql总结之SQL执行流程

312 阅读3分钟

前言

主要总结的是SQL的执行流程,顺带分析下mysql的日志文件以及缓存。

正文

Mysql查询语句处理流程

Mysql更新语句处理流程

基本流程和查询是一致的,区别是拿到符合条件的数据之后的操作。

缓冲池 Buffer Pool

对于innoDB存储引擎来说,数据都是存放在磁盘上的,存储引擎需要操作数据,必须要把磁盘里的数据加载到内存里才能操作。
InnoDB读取数据有一个最小值,即数据页(默认是16kb)。
为了提高读写效率,InnoDB设计了一个内存的缓冲池,把读取到的数据缓存起来。即Buffer Pool。

这里需要注意的是 query_cache是server端,而Buffer Pool是在存储引擎端,两者不是一个东西。

  1. 读取数据时,先判断是否存在于Buffer Pool,如果存在则直接读取返回,不存在则读取后加载到pool中,再返回。
  2. 修改数据时,也是先写入到Buffer Pool中,当内存中的数据页与磁盘页中的数据页数据不一致时,称为脏页
  3. InnoDB里面有专门的线程把Buffer Pool中的数据写入到磁盘中,即刷脏

Buffer Pool的LRU(清理机制)

  1. 所有加入到buffer pool中的数据都会放入到old sublist(冷数据区)中,如果一段时间没有访问会被移除。
  2. 在指定时间(默认1秒)后再被访问一次就会被移动到new sublisy(热数据区)。
  3. 如果new sublisy(热数据区)中的数据长时间没有被访问,会被移动到old sublist(冷数据区),渐渐移动到tail,最后被移除。

Redo.log

为了避免未被刷脏的数据因数据库宕机或者重启导致丢失,InnoDB把所有对数据的修改专门写入一个日志文件。
如果有未被同步到磁盘的数据,数据库在启动的时候,会从这个日志中进行恢复操作(实现crash-safe)。
这个日志就是Redo.log,通过这个日志文件来保证A-C-I-D中D(持久性)。

特点

  1. Redo.log是InnoDB特有。
  2. Redo.log里记录的是“在某个数据页做了哪些修改”,而不是数据更新后的状态,属于物理日志。
  3. Redo.log大小固定,前面的内容会被覆盖。一旦写满,就会触发Buffer Pool的刷盘动作,实现同步。

Undo.log

Undo.log(回滚日志)记录事务发生之前的数据状态,分为inset undo log 和 update undo log。
如果发送异常,可以利用undo.log来实现回滚操作,保证A-C-I-D中A(原子性)。

特点

1.记录的是反向操作,如果insert操作,会记录为delete,和redo.log操作不相同,成为逻辑日志。

更新过程

举例说明:
name原值为:qingshan
update语句:update teacher set name = penyuyan where name = qingsan;

  1. 事务开启,从内存(buffer pool)或磁盘(data file)获取包含这条数据的数据页,返回给Server层执行器;
  2. Server层执行器修改数据行为penyuyan;
  3. 记录set qingshan where name = penyuyan 到 undo.log
  4. 记录Set name = penyuyan where name = qingsan到 redo.log
  5. 调用存储引擎接口,记录到buffer pool中 name = penyuyan;
  6. 事务提交。

Binlog

  1. Binlog以事件的形式记录所有的DDL和DML(属于逻辑日志),可以用来做主从复制和数据恢复。
  2. 文件无固定大小限制。

举例说明:
update语句:update teacher set name = penyuyan where name = qingsan;

  1. 事务开启,从内存(buffer pool)或磁盘(data file)获取包含这条数据的数据页,返回给Server层执行器;
  2. Server层执行器修改数据行为penyuyan,调用api存入buffer pool;
  3. 记录redo.log,redo.log进入prepare状态,告诉执行器执行完成,可以提交。
  4. 执行器收到通知,记录binlog,调用api设置redo.log为commit
  5. 更新完成。