Mysql 之体系架构

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

前言

   对于Mysql我们是否有好奇过,当执行一条普通的查询语句,其内部流程是怎么样的呢 ?Mysql 整体的组成架构又是怎么样的呢?

一、Mysql 体系架构

  如下图所示(摘自Mysql官方手册),Mysql的架构分为四层,分别是Connectors层、 Server层、Enginer层、File System层。

  1. connectors (网络连接层):这一层通常对应着客户端的各种连接方式,通过不同方式获取连接池中对应的访问线程。当客户端连接到服务器时,服务器会对其进行相应的认证,比如验证用户名或密码等。这一层不算是Mysql 自带的技术,可以算是其他人针对Mysql的api开发出来的第三方技术。
  2. Server (服务层):这一层是Mysql的核心层,如上图可知其包含解析器Parser、优化器 Optimizer、查询缓存 Caches、执行器、mysql 支持的内置函数、以及所有跨存储引擎的功能都在这一层实现,如存储过程、触发器、视图等。Management Serveices & Utilities: 系统管理和控制工具,例如备份恢复、Mysql复制、集群等。
  3. Engines (存储引擎层):负责Mysql数据的存储与提取,通常用到的引擎有MyISAM和InnoDB。从Mysql5.5.5版本开始,其默认引用的是InnoDB引擎。
  4. File System(文件物理存储层):存放数据对应的物理存储文件。

     Mysql 与其他数据库最大的一个区别是,它的存储引擎是插件式的。如上图,可在存储的时候可随时切换其对应的存储引擎。存储引擎针对的是表而不是库,也就是说同一个库不同的表可引用不能的存储引擎。

二、Mysql执行过程流程

下文以一条最普通的查询语句来看查询语句在执行的过程是如何在Mysql中内部执行的。

执行语句:

mysql> select * from T where ID=10;

当我们在执行上述语句时,其在Mysql内部的逻辑执行流程基本如下图所示: 

文字解说整体流程如下:

1. 获取连接:这一步会对用户进行相应的验证,如用户名或密码等。登录成功后,服务器再对用户进行相应的操作权限进行验证。

2. 进入缓存:如开通了查询缓存功能则先进入查询缓存中进行匹配是否有对应的查询缓存存在,如果在缓存中命中则直接返回结果。这里的查询缓存是以key-value格式存储于内存的,key是查询语句,value是查询结果。

温馨提醒:开通了查询缓存功能后,对于经常进行数据更新操作的表来说会影响其操作性能。至于为什么会影响效率,我想这点肯定很容易理解。很明显就是对于频繁更新的表来说,其缓存要保证有效性那也就必须频繁进行更新。

   在Mysql中默认的缓存策略是,当数据表有更新操作执行后,查询缓存中的结果会被全部清空。因此通常来说对于更新频繁的表,不建议开启查询缓存功能。

   需要注意的是,MySQL 8.0版本直接将查询缓存的整块功能删掉了,也就是说8.0开始彻底没有这个功能了。

3. 分析器:没命中缓存就开始真正执行语句,在这一步MySQL会将SQL语句解析为树,根据语法规则对语句进行验证,比如关键字是否正确,关键字顺序是否正确,表名是否正确,字段是否正确等。

4. 优化器:在对语句进行语法分析没问题后,便会进入查询优化器,一般情况下,一条查询可以有很多种执行方式,最终返回相同的结果,优化器就是找到这其中最优的执行计划。比如,语句中运用到多个索引时,优化器会选择最优的索引;或者在多个表进行关联时,优化器会决定其执行顺序。其实这一步,跟我们通常用的explain分析语句是否走索引类似的。如下语句:

mysql> select * from t1 join t2 using(ID)  where t1.c=10 and t2.d=20;
  •  既可以先从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面 d的值是否等于20。
  • 也可以先从表t2里面取出d=20的记录的ID值,再根据ID值关联到t1,再判断t1里面c的值是否等于10。这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。

5. 执行器: 通过分析器,服务器知道语句要做什么,然后再经过优化器知道该如何做,最终就真正开始执行语句了,执行语句也就是调用引擎api进行数据提取。温馨提示:在进行真正执行语句前,会先判断该用户是否有操作该表的相应权限,在工程实现上,如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用precheck验证权限。

  比如上面这个例子中的表T中,ID字段没有索引,那么执行器的执行流程是这样的:

  1. 调用InnoDB引擎接口取这个表的第一行,判断ID值是不是10,如果不是则跳过,如果是则将这行存在结果集中;

  2. 调用引擎接口取“下一行" ,重复相同的判断逻辑,直到取到这个表的最后一行。

  3. 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

  至此,这个语句就执行完成了。

三、MyISAM和InnoDB的区别

MyISAM:

  1. 不是事务安全的;
  2. 不支持外键,如果执行大量的select,insert MyISAM比较适合;
  3. 支持表级锁,不支持行锁;
  4. 通过一个变量保存了表数据量,支持直接通过count(*)快速返回全表数据量。

InnoDB:

  1. 支持事务安全的引擎;
  2. 支持外键、表锁、行(默认)级锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况;
  3. 不支持count(*) 直接快速返回表数据量,必须进行全表扫描。

注:以上为笔者学习《MySQL实战45讲》的笔记小结。

参考:浅谈MySQL的整体架构

猜你喜欢

转载自blog.csdn.net/u013850277/article/details/94220392
今日推荐