[MySQLの戦闘-Mysql基本] -mysqlアーキテクチャ

1.基本組成

ここでのMySQLの基本的なアーキテクチャ図です。

 図I

図II

 

我々は、図から見ることができますMySQLは二つの部分に分けられ、1がサーバー層であり、他の層は、エンジンです。

サーバー層は、MySQLのコアサービスのほとんどをカバーし、コネクタ、クエリキャッシュ・アナライザ、オプティマイザ、アクチュエータなどが含まれているだけでなく、(など、時間、日付、数学、暗号化、など)組み込み関数のすべて、ストレージ全体のすべてエンジン機能は、ストアドプロシージャ、トリガ、および他のビューとして、この層に実装されています。

ストレージエンジン層は、データ記憶および検索のために責任があります。そのアーキテクチャモデルは、プラグイン、InnoDBは、MyISAMテーブル、メモリ、およびその他のストレージエンジンのためのサポートです。今、最も一般的に使用されるストレージエンジンInnoDBは、それがMysql5.5.5バージョンからデフォルトのストレージエンジンになります。

これはまた、我々はストレージエンジンの指定テーブルを構築していない場合は、InnoDBのを使用しない場合、デフォルトは、InnoDBのあることをできることを意味します   ENGINE = MEMORY  指定されたストレージエンジンを。異なるストレージ層サーバーに共通のエンジン

ここでは、より詳細な画像を見て:この図では、我々は、サーバー層に焦点を当てました

図III

 

コネクタ

図の対応するコネクタで、図すなわち2で接続プール、権限の検証を担当し、再利用スレッドの接続制限、メモリ、キャッシュなどをチェックします。

仕事はどのようにコネクタのですか?

私たちは、一般的に、MySQLの時間と対話し、常にこのコネクタに対処するための時間が、データベースに接続します。このコマンドは、接続されている:  MySQLの- H $ IP - P $港- U $のユーザーを - P  

连接成功后,我们可以使用: show processlist 来看下执行的线程(如果是super权限,看到所有的线程,否则只看到自己的)

数据库里面,长连接是指连接成功之后,如果客户端持续有请求,则一直使用同一个连接。短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。

 那么多次建立连接有什么坏处呢?

  一般来说我们jdbc连接mysql默认使用的连接协议是tcp,我们也都知道tcp建立及释放连接会经过经典的3次握手、四次分手如下图 图三,也就是一次建立与释放连接需要耗费资源的,所以一般来说会建议使用长连接。

图四

那么长连接就一定是好的吗?

  也不尽然,其实我们有时候可以发现若是全部使用长连接的话,有时候mysql占用内存涨的特别快,这是因为mysql在执行过程中使用的临时内存是管理在连接对象里面的。这些资源在连接断开的时候才会释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是MYSQL异常重启了。

  如何解决长连接的问题呢?

   1.定时断开长连接

   2.mysql 5.7及以上版本 通过执行 mysql_reset_connection为初始化连接资源,这个方法并不会释放连接,参考:https://www.docs4dev.com/docs/zh/mysql/5.7/reference/mysql-reset-connection.html#mysql-reset-connection

查询缓存

  如果是select请求的话,缓存这里会有一个key-value对的形式,key是执行的语句,value是执行出来的结果,被直接缓存到客户端。但是大多数情况下不太建议不使用查询缓存,因为查询缓存往往弊大于利。当我们做一个更新或者插入数据操作时,关于这个表的查询缓存都会被更新掉。所以查询缓存一般应用在不太使用在更新量比较多的业务中。你可以通过这句话判断是否开启缓存: show variables like '%query_cache%';  query_cache_type 为 ON 是开启缓存

需要注意的是,MySQL 8.0 版本直接将查询缓存的整块功能了。

 分析器(解析器)

   MYSQL服务中的分析器主要包含两个部分:词法分析和语法分析

    1.词法分析  在这一步,需要把一条sql语句进行分词,分词的本质便是正则表达式的匹配过程,比较流行的分词工具应该是lex,通过简单的规则制定,来实现分词。Lex一般和yacc结合使用。参考:https://www.cnblogs.com/bigshuai/articles/2363531.html

     还判断了识别出来的表名是否存在,列名是否存在

    2.语法分析:在这一步校验了sql语句的命令是否使用错误的关键字,或者使用关键字的顺序是否正确,比如 select 就不可以写成 elect

  然后会生成解析树,预处理则根据一些MySQL规则进一步检查解析树是否合法,例如,这里将检查数据表和数据列是否存在,还会解析名字和别名,看看它们是否有歧义。 

预处理:预处理器根据一些Mysql规则进一步检查解析树是否合法,如数据表数据列是否存在解析列名别名是否有歧义。接下来预处理器会验证用户权限(precheck)。查看用户是否有相应的操作权限。

优化器

  优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序,将SQL语句转化成执行计划,一条查询可以有很多种执行方式,最后都返回相同的结果,最后找到其中最好的执行计划(Mysql使用基于成本的优化器,它将尝试预测一个查询使用某种执行计划的成本,选择其中成本最小的一个)。

执行器

  1.进入执行器之后,会首先进行权限判断,如果这个账号没有对应的权限,则报错。那我们会想,如果是查询语句直接查询缓存呢? 执行过程也会在返回查询结果之前去做权限验证。

   优化器已经把sql转换为对应的执行计划,在这里会根据执行计划逐步执行。

mysql> select * from T where ID=10;

ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'

 

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

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

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

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

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

    对于有索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的

     数据库的慢查询日志中看到一个 rows_examined 的字段 ,表示这个语句执行程序中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的

执行完一条sql之后,如果是查询语句,而且缓存开启,则会把结果放入到查询缓存中。

 

 

 

参考文章: 

https://www.jb51.net/article/156752.htm

https://www.cnblogs.com/endige/archive/2012/04/11/2442534.html

https://www.cnblogs.com/renyuan/archive/2013/01/19/2867720.html

 https://blog.csdn.net/qzcsu/article/details/72861891

 https://www.cnblogs.com/jw-yahui/articles/10769563.html

おすすめ

転載: www.cnblogs.com/fengtingxin/p/11088234.html