MYSQL学习笔记(一)简单SQL的执行过程

327 阅读2分钟

1、一条普通的查询是如何执行的

SELECT a,b,c FROM test WHERE id = 101;

执行步骤

image.png

  1. 服务启动时,Mysql客户端会初始化连接池
  2. 与服务器端建立连接
  3. 用户发送请求时,tomcat线程会通过客户端链接池执行SQL语句
  4. Mysql服务器端会获取请求连接
  5. Mysql服务器端链接会由工作线程从网络链接中读取获取SQL语句
  6. 工作线程转交给SQL接口执行,SQL接口会解析SQL
  7. 交由SQL解析器按照SQL语法进行解析
  8. 查询优化器会优化解析的SQL语法,生成执行计划
  9. 执行计划交由执行器,调用存储引擎接口,执行具体SQL
  10. 访问内存数据,若内存中不存在则访问磁盘数据并加载到内存中,读取返回

数据存储结构

版本为 5.7 默认行格式:Dynamic

行结构

image.png

页结构

以页为基本单位,每页大小为16KB image.png

索引结构
普通索引

目录项_聚簇索引_结构.png

二级索引

目录项_二级索引_结构.png

通过二级索引获取到主键索引,再执行一次回表(根据主键查询B+树)获取真实数据

2、INSERT/UPDATE/DELETE 是如何执行的

image.png

  1. 找到数据对应的数据页,缓存至缓存池中
  2. 讲原始数据写入到undo log中
  3. 更新缓存数据
  4. 将数据写入到内存的redo log buffer 中
  5. 执行器准备提交事务
  6. 将redo log buffer 写入到磁盘中,处于预提交阶段
  7. 将binlog写入磁盘中
  8. 提交事务,将buffer pool 中数据刷入磁盘,commit状态;redo log 增加commit标记

undo log

www.yuque.com/docs/share/…

redo log

www.yuque.com/docs/share/…

binlog

www.yuque.com/docs/share/…

crash 数据回滚

  1. 更新 buffer pool数据后宕机: 会读取 undo log 记录的数据进行回滚
  2. 数据库二阶段提交,redo log 和 binlog 情况
    1. binlog 有记录,redo log有commit标记: 正常完成的事务,无须回滚

    2. binlog 有记录,redo log处于prepare状态: 根据binlog文件中最后一个记录的XID,去寻找是否有匹配的redo log,如果存在,则重新提交事务,redo log增加commit标记; 不存在,则回滚数据

    3. binlog 无记录,redo log处于prepare状态:回滚数据

3、Buffer Pool

www.yuque.com/docs/share/…