Architecture
Last updated
Last updated
MySQL 由 Server 层和存储引擎组成。
涵盖 MySQL 的大多数核心功能,以及所有的内置函数(如日期、时间、数学、加密等),所有跨存储引擎的功能都在这一层实现,如存储过程、触发器、视图等。
负责与客户端建立连接、获取权限、维持和管理连接。
输入正确的密码后,连接器到权限表查询权限。之后,这个链接的所有权限判断都依赖于此次读到的权限。也就是说,用户建立连接后,即使管理员对这个用户权限做了修改,不会立即生效,只有用户重新建立连接才会生效。
连接后,若没有后续请求,则连接处于空间状态,show processlist
,Command 列为 sleep表示空闲。默认空闲8小时(参数wait_timeout
控制)后,断开链接。
MySQL 执行过程中使用的内存是由连接对象管理的,这些资源在断开连接时才会释放,所以长连接累积下来,可能导致内存占用太大,被系统强行杀掉,MySQL就异常重启了。
可以定期断开长连接。
5.7后,可以执行mysql_reset_connection
来重新初始化连接资源,不会重连和做权限验证。
缓存的 key 是查询语句,value 是查询结果。若查询命中缓存,则直接返回结果。若没命中,则执行后续阶段,执行结果会存入缓存中。
MySQL 8.0删除了整块查询缓存的功能。
建议不用缓存,原因是缓存失效非常频繁,只要对一个表有更新,整个表的缓存都会清空。除非业务是静态表,基本不更新,比如系统配置表。
参数query_cache_type
设置成 DEMAND 后,SQL 默认不使用缓存,可以用 SQL_CACHE 显示指定需要缓存,如:
负责对 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 没有索引,步骤如下:
在InnoDB引擎接口获取表第一行,判断ID是否为10,不是则跳过,是则加入结果集。
调用“下一行”接口。
执行器将结果集返回给客户端。
对于有索引的表,流程类似,第一调用“取满足条件的第一行”,之后循环调用“满足条件的下一行”。这些接口都是引擎中定义好的。
在慢查询日志中有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 的每个表可以采用不同的存储引擎。