MySQL-体系结构

 

一.MySQL体系架构

 

 

一、Mysql是由SQL接口,解析器,优化器,缓存,存储引擎组成的(SQL Interface、Parser、Optimizer、Caches&Buffers、Pluggable Storage Engines)mysql

第一层:客户端redis

  并非MySQL独有的技术,它们都是服务于C/S程序或者是这些程序所须要的 :链接处理,身份验证,安全性等等算法

(1) Connectors指的是不一样语言中与SQL的交互 (并非MySQL独有的技术,它们都是服务于C/S程序或者是这些程序所须要的 :链接处理,身份验证,安全性等等)sql

第二层:SQL Layer。MySQL的核心部分数据库

  这是MySQL的核心部分。一般叫作 SQL Layer。在 MySQL据库系统处理底层数据以前的全部工做都是在这一层完成的,包括权限判断, sql解析,行计划优化, query cache 的处理以及全部内置的函数(如日期,时间,数学运算,加密)等等。各个存储引擎提供的功能都集中在这一层,如存储过程,触发器,视 图等。缓存

(2)Management Serveices & Utilities: 系统管理和控制工具,例如备份恢复、Mysql复制、集群等 
(3)Connection Pool: 链接池:管理缓冲用户链接、用户名、密码、权限校验、线程处理等须要缓存的需求 
(4)SQL Interface: SQL接口:接受用户的SQL命令,而且返回用户须要查询的结果。好比select from就是调用SQL Interface 
(5)Parser: 解析器,SQL命令传递到解析器的时候会被解析器验证和解析。解析器是由Lex和YACC实现的,是一个很长的脚本, 主要功能: 
a . 将SQL语句分解成数据结构,并将这个结构传递到后续步骤,之后SQL语句的传递和处理就是基于这个结构的 
b. 若是在分解构成中遇到错误,那么就说明这个sql语句是不合理的 
(6)Optimizer: 查询优化器,SQL语句在查询以前会使用查询优化器对查询进行优化。他使用的是“选取-投影-联接”策略进行查询。 
用一个例子就能够理解: select uid,name from user where gender = 1; 
这个select 查询先根据where 语句进行选取,而不是先将表所有查询出来之后再进行gender过滤 
这个select查询先根据uid和name进行属性投影,而不是将属性所有取出之后再进行过滤 
将这两个查询条件联接起来生成最终查询结果安全

(7) Cache和Buffer(高速缓存区): 查询缓存,若是查询缓存有命中的查询结果,查询语句就能够直接去查询缓存中取数据。 
经过LRU算法将数据的冷端溢出,将来得及时刷新到磁盘的数据页,叫脏页。 
这个缓存机制是由一系列小缓存组成的。好比表缓存,记录缓存,key缓存,权限缓存等 服务器

第三层:存储引擎层数据结构

  一般叫作StorEngine Layer ,也就是底层数据存取操做实现部分,由多种存储引擎共同组成。它们负责存储和获取全部存储在MySQL中的数据。就像Linux众多的文件系统 同样。每一个存储引擎都有本身的优势和缺陷。服务器是经过存储引擎API来与它们交互的。这个接口隐藏 了各个存储引擎不一样的地方。对于查询层尽量的透明。这个API包含了不少底层的操做。如开始一个事 物,或者取出有特定主键的行。存储引擎不能解析SQL,互相之间也不能通讯。仅仅是简单的响应服务器 的请求多线程

(8)Engine :存储引擎。存储引擎是MySql中具体的与文件打交道的子系统。也是Mysql最具备特点的一个地方。 
Mysql的存储引擎是插件式的。它根据MySql AB公司提供的文件访问层的一个抽象接口来定制一种文件访问机制(这种访问机制就叫存储引擎) 
如今有不少种存储引擎,各个存储引擎的优点各不同,最经常使用的MyISAM,InnoDB,BDB 
默认下MySql是使用MyISAM引擎,它查询速度快,有较好的索引优化和数据压缩技术。可是它不支持事务。 
InnoDB支持事务,而且提供行级的锁定,应用也至关普遍。 
Mysql也支持本身定制存储引擎,甚至一个库中不一样的表使用不一样的存储引擎,这些都是容许的 

 

一条SQL的执行过程

 MySQL是单进程,多线程

链接管理和安全

在服务器内部,每一个client链接都有本身的线程。这个链接的查询都在一个单独的线程中执行。这些线程轮流运行在某一个CPU内核(多核CPU)或者CPU中。服务器缓存了线程,所以不须要为每一个client链接单首创建和销毁线程 。

当clients(也就是应用程序)链接到了MySQL服务器。服务器须要对它进行认证(Authenticate)。认证是基于用户名,主机,以及密码。对于使用了SSL(安全套接字层)的链接,还使用了X.509证书。clients一链接上,服务器就验证它的权限 (如是否容许客户端能够查询world数据库下的Country表的数据)。

优化和执行

MySQL会解析查询,并建立了一个内部数据结构(解析树)。而后对其进行各类优化。这些优化包括了,查询语句的重写,读表的顺序,索引的选择等等。用户能够经过查询语句的关键词传递给优化器以便提示使用哪一种优化方式,这样即影响了优化器的优化方式。另外,用户也能够请求服务器给出优化过程的各类说明,以获知服务器的优化策略,为用户提供了参数基准,以便用户能够重写查询,架构和修改相关服务器配置,便于mysql更高效的运行。

优化器并是不关心表使用了哪一种存储引擎,可是存储引擎对服务器优化查询的方式是有影响的。优化器须要知道存储引擎的一些特性:具体操做的性能和开销方面的信息,以及表内数据的统计信息。例如,存储引擎支持哪些索引类型,这对于查询是很是有用的。

在解析查询以前,要查询缓存,这个缓存只能保存查询信息以及结果数据。若是请求一个查询在缓存 中存在,就不须要解析,优化和执行查询了。直接返回缓存中所存放的这个查询的结果。

二.MySQL内存结构

Mysql 内存分配规则是:用多少给多少,最高到配置的值,不是当即分配。

实际上MySQL内存的组成和Oracle相似,也能够分为SGA(系统全局区)和PGA(程序缓存区)。

mysql>show variables like "%buffer%";

1、SGA

1.innodb_buffer_pool

用来缓存Innodb表的数据、索引、插入缓冲、自适应哈希索引,锁信息,数据字典等信息。

2.innodb_log_buffer

事务在内存中的缓冲,即red log buffer的大小

3.query cache

高速查询缓存,在生产环境中建议关闭。

4.key_buffer_size

用于MyISAM存储引擎,缓存MyISAM存储。

引擎表的索引文件(区别于innodb_buffer_poll数据和索引缓存)

5.innodb_additional_mem_pool_size

用来缓存数据字典信息和其它内部数据结构的内存池的大小。MySQL5.7.4中该参数取消。

 

2、PGA

1.sort_buffer_size(排序缓冲大小,提升排序效率)

主要用于SQL语句在内存中的临时排序

2.join_buffer_size

表链接使用,用于BKA,MySQL5.6以后开始支持。

3.read_buffer_size(顺序读缓冲大小,提升顺序都效率)

表顺序扫描的缓存,只能应用于MyISAM表存储引擎。

4.read_rnd_buffer_size(随机缓冲大小,提升随机都效率)

MySQL随机读缓冲区大小,用于作mrr,mrr是MySQL5.6以后才有的特性。

5.tmp_table_size

SQL语句在排序或分组时没有用到索引,就会使用临时表空间。

6.max_heap_table_size

管理heap,memory存储引擎表。

 


一、全局内存(Global buffer)

(1)innodb_buffer_pool_size:

(1.1) innodb高速缓冲data和索引,简称IBP,这个是Innodb引擎中影响性能最大的参数。建议将IBP设置的大一些,单实例下,建议设置为可用RAM的50%~80%。 (1.2)innodb不依赖OS,而是本身缓存了全部数据,包括索引数据、行数据等等,这个和myisam有差异。 (1.3)IBP有一块buffer用于插入缓冲,在插入时,先写入内存以后再合并后顺序写入磁盘;在合并到磁盘的时候会引起较大的IO操做,对实际操做形成影响。(看上去的表现是抖动,TPS变低) (1.4)show global status like ‘innodb_buffer_pool_%’ 查看IBP状态,单位是page(16kb),其中,Innodb_buffer_pool_wait_free 若是较大,须要加大IBP设置 (1.5)InnoDB会定时(约每10秒)将脏页刷新到磁盘,默认每次刷新10页;要是脏页超过了指定数量(innodb_max_dirty_pages_pct),InnoDB则会每秒刷100页脏页 (1.6)innodb_buffer_pool_instances能够设置pool的数量 (1.7)show engine innodb status\G 能够查看innodb引擎状态

 

(2)innodb_additional_mem_pool_size:

(2.1)指定InnoDB用来存储数据字典和其余内部数据结构的内存池大小。缺省值是8M(8388608)。一般不用太大,只要够用就行,应该与表结构的复杂度有关系。若是不够用,MySQL会在错误日志中写入一条警告信息。5.7版本已经弃用这个参数

(3)innodb_log_buffer_size:

(3.1)innodb redo日志缓冲,提升redo写入效率。若是表操做中包含大量并发事务(或大规模事务),而且在事务提交前要求记录日志文件,请尽可能调高此项值,以提升日志效率。
(3.2)show global status 查看 Innodb_log_waits 是否大于0,是的话,就须要提升 innodb_log_buffer_size,不然维持原样。
(3.3)show global stauts 查看30~60秒钟 Innodb_os_log_written 的间隔差别值,便可计算出 innodb_log_buffer_size 设置多大合适。

默认8M,通常设置为16 ~ 64M足够了。 
 
(4)key_buffer_size:

(4.1)myisam引擎中表的索引 的缓存大小,默认值=16M;单个key_buffer_size最大只有4G(32-bit系统下最大4G,64-bit下能够超过)
(4.2)若主要使用myisam存储引擎,则设置最高不超过物理内存的20%~50%,
(4.4)即使全是innodb表,没用MyISAM,也有必要设置key_buffer_size用于缓存临时表的索引,推荐设置32MB
(4.5)关于临时表,若是内存tmp_table_size(Created_tmp_tables)不够的话,内部的临时磁盘表是MyISAM表(Created_tmp_disk_tables)。show global status like 'Create%'; show variables like 'tmp%';

(5)query_cache_size :

查询高速缓冲,缓存结果,减小硬解析(建议关闭,若是真须要查询缓存能够借助redis等缓存),最好是关闭

(6)table_definition_cache:

(6.1)表定义文件描述缓存,提升表打开效率。是frm文件在内存中的映射。MySQL须要打开frm文件,并将其内容初始化为Table Share 对象。这里存放与存储引擎无关的,独立的表定义相关信息。

(7)table_open_cache:

(7.1)表空间文件描述缓冲,提升表打开效率。
(7.2)增长table_open_cache,会增长文件描述符(ulimit -a查看系统的文件描述符),当把table_open_cache设置的过大时,若是系统处理不了这么多文件描述符,那么就会出现客户端失效、链接不上。
(7.3)table_open_cache,也就是平时说的table cache。存放当前已经打开的表句柄,与表建立时指定的存储引擎相关。请注意和table_define_cache参数的区别。

为何MySQL会出现table_open_cahce和table_define_cache这两个概念? 
是由于:MySQL支持不一样的存储引擎,每种存储引擎,数据存储的格式都是不同的,所以须要指定一个存储引擎相关的handler。这就有了table cache的做用(table_open_cache参数)。另外表的定义也须要存放内存中,而表的定义frm文件每一个存储引擎是通用的,须要另外独立开来,这就有了table definition cache。

(8)max_heap_table_size和tmp_table_size:

(8.1)max_heap_table_size 参数:定义了MEMORY、HEAP表的最大容量,若是内存不够,则不容许写入数据
(8.2)tmp_table_size参数:规定了内部内存临时表的最大值,每一个线程都要分配。(实际起限制做用的是tmp_table_size和max_heap_table_size的最小值。)若是内存临时表超出了限制,MySQL就会自动地把它转化为基于磁盘的MyISAM表,存储在指定的tmpdir目录下。
(8.3)优化查询语句的时候,要避免使用临时表,若是实在避免不了的话,要保证这些临时表是存在内存中的,不然临时表超过内存临时表的限制,会自动转化为基于磁盘的Myisam表。

二、线程内存(Thread buffer)

(1)read_buffer_size:

是MySQL读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。若是对表的顺序扫描请求很是频繁,而且你认为频繁扫描进行得太慢,能够经过增长该变量值以及内存缓冲区大小提升其性能。

(2)read_rnd_buffer_size:

是MySQL的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySQL会首先扫描一遍该缓冲,以免磁盘搜索,提升查询速度,若是须要排序大量数据,可适当调高该值。但MySQL会为每一个客户链接发放该缓冲空间,因此应尽可能适当设置该值,以免内存开销过大。

(3)sort_buffer_size:

是MySQL执行排序使用的缓冲大小。若是想要增长ORDER BY的速度,首先看是否可让MySQL使用索引而不是额外的排序阶段。若是不能,能够尝试增长sort_buffer_size变量的大小。

(4)join_buffer_size:

应用程序常常会出现一些两表(或多表)Join的操做需求,MySQL在完成某些 Join 需求的时候(all/index join),为了减小参与Join的“被驱动表”的读取次数以提升性能,须要使用到 Join Buffer 来协助完成 Join操做。当 Join Buffer 过小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与须要 Join 的表进行 Join 操做,而后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer 中,如此往复。这势必会形成被驱动表须要被屡次读取,成倍增长 IO 访问,下降效率。

(5)binlog_cache_size:

在事务过程当中容纳二进制日志SQL 语句的缓存大小。二进制日志缓存是服务器支持事务存储引擎而且服务器启用了二进制日志(—log-bin 选项)的前提下为每一个客户端分配的内存,注意,是每一个Client 均可以分配设置大小的binlog cache 空间。若是系统中常常会出现多语句事务的话,能够尝试增长该值的大小,以得到更好的性能。固然,咱们能够经过MySQL 的如下两个状态变量来判断当前的binlog_cache_size 的情况:Binlog_cache_use 和Binlog_cache_disk_use。“max_binlog_cache_size”:和"binlog_cache_size"相对应,可是所表明的是binlog 可以使用的最大cache 内存大小。当咱们执行多语句事务的时候,max_binlog_cache_size 若是不够大的话,系统可能会报出“ Multi-statement transaction required more than 'max_binlog_cache_size' bytes ofstorage”的错误。
其中须要注意的是:table_cache表示的是全部线程打开的表的数目,和内存无关。

(6)tmp_table_size:

是MySQL的临时表缓冲大小。全部联表查询在一个DML指令内完成,而且大多数联合甚至能够不用临时表便可以完成。大多数临时表是基于内存的(HEAP)表。具备大的记录长度的临时表 (全部列的长度的和)或包含BLOB列的表存储在硬盘上。若是某个内部heap(堆积)表大小超过tmp_table_size,MySQL能够根据须要自动将内存中的heap表改成基于硬盘的MyISAM表。还能够经过设置tmp_table_size选项来增长临时表的大小。也就是说,若是调高该值,MySQL同时将增长heap表的大小,可达到提升联接查询速度的效果。

(7)thread_stack :

主要用来存放每个线程自身的标识信息,如线程id,线程运行时基本信息等等,咱们能够经过 thread_stack 参数来设置为每个线程栈分配多大的内存。每一个链接线程被建立时,MySQL给它分配的内存大小。当MySQL建立一个新的链接线程时,须要给它分配必定大小的内存堆栈空间,以便存放客户端的请求的Query及自身的各类状态和处理信息。

(8)thread_cache_size:

若是咱们在MySQL服务器配置文件中设置了thread_cache_size,当客户端断开以后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)。

(9)net_buffer_length:

客户发出的SQL语句指望的长度。若是语句超过这个长度,缓冲区自动地被扩大,直到max_allowed_packet个字节。

(10)bulk_insert_buffer_size:

若是进行批量插入,能够增长bulk_insert_buffer_size变量值的方法来提升速度,可是,这只能对myisam表使用。

三、overhead

(1)自适应哈希索引(Adaptive index hash)

(1.1)哈希索引是一种很是快的等值查找方法(注意:必须是等值,哈希索引对非等值查找方法无能为力),它查找的时间复杂度为常量,InnoDB采用自适用哈希索引技术,它会实时监控表上索引的使用状况,若是认为创建哈希索引能够提升查询效率,则自动在内存中的“自适应哈希索引缓冲区”中创建哈希索引。
(1.2)之因此该技术称为“自适应”是由于彻底由InnoDB本身决定,不须要DBA人为干预。它是经过缓冲池中的B+树构造而来,且不须要对整个表创建哈希索引,所以它的数据很是快。
(1.3)InnoDB官方文档显示,启用自适应哈希索引后,读和写性能能够提升2倍,对于辅助索引的链接操做,性能能够提升5被,所以默认状况下为开启,能够经过参数innodb_adaptive_hash_index来禁用此特性。
(1.4)哈希索引老是基于表上已存在的B树索引来创建的。InnoDB会在为该B树定义的键的一个前缀上创建哈希索引,无论该键有多长。哈希索引能够是部分的:它不要求整个B树索引被缓存在缓冲池中。InnoDB根据须要对被常常访问索引的那些页面创建哈希索引。

(2)System dictionary hash (3)Locking system (4)Sync_array (5)Os_events

相关文章
相关标签/搜索