Architecture

MySQL 由 Server 层存储引擎组成。

Server层

涵盖 MySQL 的大多数核心功能,以及所有的内置函数(如日期、时间、数学、加密等),所有跨存储引擎的功能都在这一层实现,如存储过程、触发器、视图等。

连接器

负责与客户端建立连接、获取权限、维持和管理连接。

mysql -h $ip -P $port -u $user -p

输入正确的密码后,连接器到权限表查询权限。之后,这个链接的所有权限判断都依赖于此次读到的权限。也就是说,用户建立连接后,即使管理员对这个用户权限做了修改,不会立即生效,只有用户重新建立连接才会生效。

连接后,若没有后续请求,则连接处于空间状态,show processlist,Command 列为 sleep表示空闲。默认空闲8小时(参数wait_timeout控制)后,断开链接。

MySQL 执行过程中使用的内存是由连接对象管理的,这些资源在断开连接时才会释放,所以长连接累积下来,可能导致内存占用太大,被系统强行杀掉,MySQL就异常重启了。

  1. 可以定期断开长连接。

  2. 5.7后,可以执行mysql_reset_connection来重新初始化连接资源,不会重连和做权限验证。

查询缓存

缓存的 key 是查询语句value 是查询结果。若查询命中缓存,则直接返回结果。若没命中,则执行后续阶段,执行结果会存入缓存中。

MySQL 8.0删除了整块查询缓存的功能。

建议不用缓存,原因是缓存失效非常频繁,只要对一个表有更新,整个表的缓存都会清空。除非业务是静态表,基本不更新,比如系统配置表。

参数query_cache_type设置成 DEMAND 后,SQL 默认不使用缓存,可以用 SQL_CACHE 显示指定需要缓存,如:

select SQL_CACHE * from T where ID=10;

分析器

负责对 SQL 做解析。

  • 词法分析:识别出由字符串和空格组成的 SQL 语句中的字符串。比如select * from T where ID=10,会把 T 识别成表名,ID 识别成列。

  • 语法分析:判断 SQL 语句是否合法,若不合法,会收到 “You have an error in your SQL” 的错误。

优化器

  • 决定是否使用或者使用哪个索引。

  • 决定多表关联(join)时各个表的连接顺序。

执行器

首先判断是否有权限(之前若缓存命中,也会执行权限验证)。

根据表的引擎定义,使用对应引擎的接口。还是以select * from T where ID=10为例,假设 ID 没有索引,步骤如下:

  1. 在InnoDB引擎接口获取表第一行,判断ID是否为10,不是则跳过,是则加入结果集。

  2. 调用“下一行”接口。

  3. 执行器将结果集返回给客户端。

对于有索引的表,流程类似,第一调用“取满足条件的第一行”,之后循环调用“满足条件的下一行”。这些接口都是引擎中定义好的。

在慢查询日志中有row_examined字段,表示执行过程扫描了多少行,是在每次调用引擎获取数据行时累加的。

有些场景,执行器调用一次,引擎扫描多行,因此引擎扫描行数与row_examined并不完全相同。

存储引擎

  • 负责数据的存储和提取。

  • 插件式架构,支持 InnoDB、MyISAM、Memory 等,从 5.5.8 版本开始默认为 InnoDB。

  • 可以通过 create table 的时候指定 engine 来选择存储引擎。

  • 不同的存储引擎公用一个 Server 层。

常见的存储引擎特性:

  • InnoDB:5.5.8 之后的默认引擎,特点是支持事务、行级锁、外键等;

  • MyISAM:5.5.8 之前的默认引擎,不支持事务,不支持外键,特点是速度快、占用资源少;

  • Memory:会丢失数据,速度更快;

  • NDB:也叫 NDB Cluster,用于 MySQL Cluster 的分布式集群;

  • Archive:很好的压缩机制,用于文件归档。

MySQL 的每个表可以采用不同的存储引擎。

Last updated