基础架构
1,MySQL可以分为Server层和存储引擎层。
1)Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如:存储过程、触发器、视图等。
2)存储引擎层负责数据的存储和读取,它的架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎,最常见的存储引擎是InnoDB,从5.5.5版本后为默认存储引擎。
3)可以在create table建表的时候使用engine=memory指定内存引擎。
2,不同的存储引擎共用一个Server层,从连接器到执行器。
一条SQL查询语句的执行
1,连接器,先连接到数据库上,由连接器负责跟客户端建立连接、获取权限、维持和管理连接。
1)输入连接命令mysql -h$ip -P$port -u$user -p$pwd,也可以省略密码输入命令后在交互对话输入密码,如果连接的生产服务器,建议-p后不输入密码。
2)连接命令中的mysql是客户端工具,与服务器建立连接。
3)在完成经典的TCP握手后,连接器需要认证身份,用户名密码通过认证后,在权限表查询用户的权限,并在当前连接周期中保持该权限。
4)管理员修改用户权限不影响已经建立连接的权限。
5)连接完成后,如果没有后续操作,连接处于空闲状态,长时间的空闲连接器会自动断开,断开时间参数由wait_timeout控制,默认为8小时,断开后需要重新建立连接再执行其他请求。
6)数据库连接成功后,客户端的持续请求使用同一个连接为长连接,执行完几个请求就断开连接,再请求重新建立连接为短连接。
7)建立连接的过程比较复杂,建议尽量使用长连接,但长连接会造成内存占用过大的问题,MySQL在执行过程中使用的临时内存是管理在连接对象里的,连接断开时才会释放。如果长连接累积导致内存占用太大,系统会强行杀掉(OOM),所以需要定期断开长连接,或者在执行一个占用内存的大查询后断开连接。
8)MySQL5.7之后的版本在执行完占用内存的操作后,可通过执行mysql_reset_connection重新初始化连接资源,不需要重连和权限验证,将连接恢复到初始状态。
2,查询缓存,连接建立后,执行查询请求会先查缓存,之前执行过的语句及结果以key-value对的形式缓存在内存中,如果缓存中存在查询结果直接将结果返回,如果缓存中不存在继续后面的执行,执行完成后,将结果存入查询缓存。
1)查询缓存失效比较频繁,当有表的更新时,表上所有查询缓存都会清空。
2)更新压力较大的数据,查询缓存的命中率较低。
3)MySQL8.0以后的版本删除了查询缓存功能。
3,分析器,如果没有命中查询缓存,执行SQL语句需要先解析语句,分析器先做词法分析,识别关键字、表名等,再做语法分析,根据语法规则判断SQL语句是否合法,明确语句要干什么。
4,优化器,表里有多个索引时,优化器决定使用哪个索引,或语句中有多表关联(join)时决定表的连接顺序,优化器决定了语句的执行方案。
5,执行器,执行前判断对相应的表是否有权限,如果有权限,打开表根据表的引擎使用引擎接口执行语句,select * from T where ID=10;
1)如果表T中ID字段没有索引,调用InnoDB引擎接口取表的第一行,判断ID值是不是10,不是则跳过,是则将这行存在结果集中;调用引擎接口取下一行,重复相同的判断逻辑,直到表的最后一行;将遍历过程中的结果集返回。
2)如果表T中ID字段有索引,调用引擎接口取满足条件的第一行,将结果存入结果集;调用引擎接口取满足条件的下一行;这些接口都是引擎中定义好了的。
3)在数据库的慢查询日志中rows-examined的字段,表示执行器调用引擎次数。有些场景下,执行器调用一次,引擎内部扫描了多行,所以rows-examined与引擎扫描行数不一定相同。
4)在命中查询缓存时,会在查询缓存返回结果前验证权限。