MySQL系列 - SQL查询与修改执行过程
我们平时都是输入一条语句,返回结果。那么,这条语句在MySQL内部的执行过程是什么样的呢?
select * from tab1 where id = 1;
MySQL的逻辑架构
首先我们来看MySQL的基本逻辑架构示意图

Server
MySQL的核心服务功能。
查询解析、分析、优化、缓存
所有的内置函数:日期、时间、数学与加密函数等
所有的跨存储引起 的功能都在这一层实现:存储过程、触发器、视图
存储引擎
数据的存储与提取。
每个存储引擎都有它的优势与劣势。
Server层通过API接口与存储引擎通信,屏蔽不同引擎的差异。
存储引擎不会解析SQL(InnoDB的外键定义解析是例外)。
连接管理与安全性
每个客户端通过服务端的连接器:建立连接、获取权限、维持连接、管理连接。
mysql -h$ip -P$port -u$user -p
长连接与短链接
连接建立的过程是比较复杂的,所以我们尽量使用长连接。
但是要注意内存情况,查询过程中临时使用的内存式管理在连接对象里面的,这些资源会在连接断开的时候才释放。所以随着长连接基类下来,可能会产生OOM。
优化与执行
查询缓存
一个查询请求会先查询一个对大小写敏感的哈希缓存,看之前是否执行过,假如匹配到了,直接返回结果给客户端。
但是,查询缓存会跟踪查询中涉及的每张表,如果这些表有数据变化,那么和这个表相关的所有缓存都将失效。所以对于一个线上业务的表来说,查询缓存是弊大于利的,因为频繁的缓存和失效会带来更多的消耗。MySQL 8.0 +开始直接将查询缓存的整块功能删掉了。
解析与优化
MySQL会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引。
Tips:
用户可以通过关键帧提示优化器,影响它的决策过程。
可以通过 解释优化过重中的各个因素,使用户知道优化器如何决策,提供一个参考基准,便于用户重构查询与Schema,优化配置。
优化器不关心使用的是什么存储引擎,但存储引擎对优化查询是有影响的,所以优化器会请求存储引擎的一些“元”数据,比如表数据统计信息、容量、操作开销等。
慢查询中的 就是指执行器扫描了多少行。
数据更新
相比于查询流程,数据更新基于WAL(Write-Ahead Log)。
Binary Log、Redo Log
Binlog 是 MySQL 本身提供的一种逻辑日志,和具体存储引擎无关,描述的是数据库所执行的 SQL 语句或数据变更情况,主要用于数据复制。
Redo Log 是 InnoDB 存储引擎提供的一种物理日志结构,用来描述对底层数据页操作的具体内容,主要用于实现 crash-safe,并将部分随机 IO 写变为顺序写,提升磁盘操作效率。
这个参数设置成1表示每次事务的redo log都持久化到磁盘

两阶段提交
两阶段提交不是 Redo Log 或 InnoDB 中的设计,而是 MySQL 服务器的设计。MySQL是插件化的存储引擎设计,事务提交时,服务器本身与存储引擎都需要提交数据,所以从整体来看,其本身就面临着分布式事务问题。
MySQL 执行器和 InnoDB 存储引擎在执行简单 update 语句 时的流程(因为此例只执行单条更新语句,所以其自身就是一个事务)。

小结
关于具体的优化与执行点:重写查询、决定表的读取顺序,以及选择合适的索引会在该系列其他文章详细解读。
分布式事务的两段提交(2PC)、三段提交(3PC)、共识算法(VSR、Paxos、Raft、Zab等)与全序广播,也会出专门的文章讲解。