目录

【MySQL】基本架构

MySQL 基本架构

MySQL主要由以下几个功能模块组成:

  1. 连接器。

  2. 查询缓存。

  3. 分析器。

  4. 优化器。

  5. 执行器。

  6. 存储引擎。

server层:

连接器、查询缓存、分析器、优化器、执行器组成了server层。

该层包含了所有的内置函数,所有的跨存储引擎功能也都在这一层,如存储过程、触发器、视图等。

存储引擎层:

存储引擎模块属于存储引擎层。

该层负责数据的存储和提取,其架构模式是插件式。

可以使用show engines查看引擎信息。MySQL5.5.5之后默认使用InnoDB

连接器

连接器,用于管理连接,权限验证。

创建连接

连接命令一般为:

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

完成TCP握手后,连接器开始认证身份,此时会用到输入的用户名和密码。

如果用户名或者密码不对,返回"Access denied for user"

如果认证通过,连接器会到权限表获取用户拥有的权限,用于之后所有的权限判断逻辑。

如果该用户的权限被修改,对于已通过认证的连接,拥有的权限不会受影响。只有重新建立连接,才会使用新权限。

空闲连接

建立连接后,如果没有后续动作,该连接就处于空闲状态。可以使用show processlist查看空闲中的连接。

如果一直保持空闲状态,到一定时间连接器会将这个连接断开,该时间受wait_timeout控制,默认为8小时。

连接断开后,该连接再次发送请求的话,就会收到一个错误提醒。

长连接和短连接

长连接是指,连接成功后,后续的请求一直使用同一个连接。

短链接是指,连接成功后,只执行完成很少的几次查询,就断开连接,下次查询时再重新建立一个。

建立连接的过程比较复杂,所以应尽量使用长连接。但是在MySQL中,使用长连接也会存在问题。

MySQL执行过程中临时使用到的内存,是管理在连接对象里面的,在连接断开时,资源才会释放。如果长连接一直积累,就会导致内存占用太大,被系统强行杀掉,从而导致MySQL异常重启。

要解决长连接问题,可以考虑两种方案:

  • 定期断开长连接。

  • MySQL5.7或之后版本,每次执行完一个较大操作,可以使用mysql_reset_connection来初始化连接资源,包括事务回滚、锁释放等。初始化过程中,不会重连和重新验证权限,只会恢复到连接刚刚创建完的状态。

查询缓存

之前的查询语句和结果,会以key-value对的形式,缓存在内存中。如果查询时能在缓存中找到这个key,那么value会被直接返回。如果找不到,才继续后面的阶段。

返回结果的时候,会做权限验证。

按需使用

查询缓存的失效非常频繁,一个表只要有更新,这个表上的所有查询缓存都会被清空。对于更新压力大的数据库来说,查询缓存的命中率非常低。

静态表可以使用查询缓存,如系统配置相关表。

MySQL8.0已经删除了查询缓存。其它版本可以通过设置query_cache_type进行控制。

query_cache_type

该参数有三个不同的值:

  • OFF:关闭查询缓存。

  • ON:缓存所有结果,除非在select语句中使用SQL_NO_CACHE禁止缓存。

  • DEMAND:在select语句中使用SQL_CACHE时进行缓存。

分析器

分析器会进行词法分析、语法分析。

除了检查语法对不对之外,还会检查库名、表名和字段名是否正确。

优化器

优化器会根据SQL语句,生成多个查询路径树,然后从中选择一个最优解。如有多个索引时,决定使用哪个索引;使用join时,决定各个表的连接顺序等。

使用优化器之前,会调用precheck验证权限。

执行器

根据表的引擎定义,调用对应的引擎接口,从而完成SQL语句的执行。

执行前,需要判断一下是否有表的执行权限。

查询的执行流程

现在以查询语句为例,说明执行器的执行流程。

对于无索引数据:

  • 调用接口取这个表的第一行。
  • 如果满足要求就加入结果集,如果不满足就跳过。
  • 直到这个表的最后一行,然后将结果集返回客户端。

对于有索引数据:

  • 取满足条件的第一行,加入结果集。
  • 循环取满足条件的下一行。

rows_examined

慢查询日志中有一个rows_examined参数,表示语句执行过程中扫描了多少行。

执行器每次调用引擎获取数据时,会对rows_examined进行累加,即该值等于执行器通过引擎接口获取的数据行数。

但是执行器每调用一次接口,引擎内部可能扫描多行。