MySQL架构
MySQL8.0服务器是由连接池、服务管理⼯具和公共组件、NoSQL接⼝、SQL接⼝、解析器、优化
器、缓存、存储引擎、⽂件系统组成。MySQL还为各种编程语⾔提供了⼀套⽤于外部程序访问服务器的连接器。整体架构图如下所⽰:
- MySQL Connectors:为使⽤MySQL服务的编程语⾔平台,提供了访问接⼝,可以根据⾃⼰实际使⽤的编程语⾔到官⽹下载地址下载。
- MySQL Shell:是⼀个⾼级客⼾端和代码编辑器,以组件的形式提供,需要单独安装。除了提供的类似于 mysql 客⼾端的功能,还可以使⽤ JavaScript 和 Python 调⽤MySQL 的API,⼀般为开发 ⼈员使⽤。
- 连接层:对客⼾端连接进⾏权限校验并保存客⼾端的连接信息,通过池化技术实现线程重⽤,以及根据具体的配置限制连接数量。
- 服务管理和公共组件:提供了数据备份与恢复,安全组件,主从复制和集群管理,表分区等实⽤功能。
- 服务层:提供了NoSQL API, SQL API, SQL语句解析,SQL语句优化,SQL语句缓存等组件,并将优化后的SQL语句发送⾄存储引擎执⾏相应的操作并返回结果。
- 存储引擎层:⼀系列可插拔的存储引擎,主要负责数据的写⼊和读取,与底层的数据和⽇志⽂件进⾏交互,可以根据具体的业务需求选择不同的存储引擎,后⾯我们具体介绍他们之间的区别。
- ⽂件系统层:包含了MySQL发⾏版的⽂件和程序,以及具体数据库⽂件和⽇志。
接下来我们介绍各层级在整个MySQL服务器中实现的功能。
连接层
连接层的作⽤是处理客⼾端的连接,这里主要介绍MySQL Server如何管理连接,包括对可⽤连接接⼝的描述和服务器如何使⽤连接处理线程。
网络端口和连接管理线程
MySQL是一个网络服务,通过 IP+端口号 就可以找到网络上指定的一个MySQL服务。 ⼀台服务器能够侦听多个⽹络端⼝上的客⼾端连接,开放多个端⼝,只需在选项⽂件 /etc/mysql/my.cnf 中指定多个端⼝ 即可,配置如下所⽰:
[mysqld] # mysqld节点
port=3306 # 端⼝1
port=3307 # 端⼝2
比如,我们设置了 mysqld 服务的端口号为3306和3307,那么我们在启动 mysql 客户端程序的时候就需要向操作系统申请这两个端口号中的一个,进而可以来访问 mysqld 服务。
通过连接管理器线程处理端⼝上的客⼾端连接请求:
- 在所有平台上,⽤⼀个管理器线程处理所有的 TCP/IP 连接请求。
- 在 Unix 上,管理器线程还可以处理其他Unix socket 连接请求。
- 在 Windows 上,使⽤⼀个管理器线程处理通过Shared-memory⽅式连接请求,使⽤另⼀个管理器线程处理Named-pipe⽅式连接请求。
- 在所有平台上,可以额外启⽤⼀个端⼝⽤于接受针对管理的 TCP/IP 连接请求,管理端⼝的连接可以使⽤处理"普通" TCP/IP 请求的管理器线程,也可以通过选项⽂件配置单独的线程。
客户端连接线程管理
连接管理器线程在接收到每个客⼾端连接后,把请求转发到真正的执⾏线程,每个请求都对应⼀个执⾏线程,该线程处理连接的⾝份验证和具体请求。执⾏线程使⽤线程池技术进⾏缓存,当⼀个请
求需要处理时,先从线程池中查找是否有可⽤的线程,如果没有则新创建⼀个,当连接结束时,如果线程池没有满,则把当前线程放⼊线程池,主要的作⽤是提⾼线程的复⽤,减少创建线程造成的系统开销从⽽提⾼效率。
可以通过以下⼏个系统变量和状态变量控制和监视服务器管理客⼾端连接的线程:
- 系统变量 thread_cache_size 决定了线程池缓存的⼤⼩。默认情况下,服务器在启动时会⾃动调整这个值,但也可以通过选项⽂件明确指定⼤⼩,值为 0 时禁⽤缓存,此时为每个新连接创建执⾏⼀个线程,并在连接断开时释放
- 有些复杂的SQL语句在执⾏过程中可能会有深层递归从⽽消耗更多的内存,通过设置thread_stack=N 调整线程堆栈⼤⼩
- 要查看缓存中的线程数以及超过缓存数后新创建的线程数,通过状态变量 Threads_cached 和 Threads_created 查看
[mysqld] # mysqld节点
thread_cache_size=16 #线程池⼤⼩
thread_stack=1048576 #堆栈内存⼤⼩
连接量管理
- 系统变量 max_connections 可以控制服务器允许同时连接的最⼤客⼾端数,当服务器达到max_connections 指定的连接数时会拒绝所有新的连接请求,同时会增加状态变量Connection_errors_max_connections 的值
- mysqld实际上允许 max_connections+1 个客⼾端连接。额外的连接为拥有 connection_admin 权限的帐⼾(管理员)使⽤,即使普通连接达到了 max_connections 的数量,管理员也可以连接到服务器进⾏管理操作;
- 在部署为主从复制的环境中,从节点的连接数也会计⼊ max_connections 中,如果连接达到上限主从复制将会失败
- max_connections 具体数据和服务器的硬件有关,⽐如可⽤的内存、每个连接消耗的内存,每个连接的⼯作负载、响应时间、可⽤⽂件描述符的数量等等
服务层
数据库服务层是整个数据库服务器的核⼼,主要包括了服务管理和公共组件、NoSQL和SQL接⼝、解析器、查询优化器和缓存等部分,下⾯我们分别介绍每个部分的作⽤:
服务管理和公共组件
MySQL提供了多种功能服务以满⾜不同使⽤场景下的需要,常⽤的服务如下:
- Backup & Recovery:备份与恢复。MySQL的备份与恢复服务允许用户创建数据库的副本(备份),以便在数据丢失、损坏或意外删除等情况下,可以从备份中还原数据库到之前的某个状态。
- Security:安全。MySQL通过各种机制来确保安全性。这包括用户认证、授权(确定用户对数据库对象,如表格、视图等有哪些操作权限,例如查询、插入、更新、删除等权限)、加密(对敏感数据进行加密存储,使得即使数据被窃取,没有解密密钥也无法获取真实内容)等方面的功能。
- Replication:主从复制。主从复制是一种用于提高数据库可用性、扩展性和数据安全性的技术。在MySQL中,有一个主数据库(Master)和一个或多个从数据库(Slave)。主数据库负责处理所有的写操作(如插入、更新、删除数据等),而从数据库则复制主数据库的数据变化并保持与主数据库的数据一致性。从数据库主要用于读操作,这样可以分担主数据库的读负载,提高整个系统的性能。同时,从数据库也可以作为主数据库的备份,在主数据库出现故障时,可以切换到从数据库继续提供服务。
- Cluster:MySQL集群。MySQL集群是一种将多个MySQL服务器组合在一起,共同提供数据库服务的技术。通过集群,可以实现高可用性(避免单点故障,当某个节点出现问题时,其他节点可以继续提供服务)、可扩展性(可以方便地添加新的节点来处理更多的负载)和高性能(多个节点并行处理数据库操作)等目标。
- Partitioning:表分区。表分区是将一个大的表按照特定的规则分成多个较小的、更易于管理的子表(分区)的技术。例如,可以按照时间(如每月的数据作为一个分区)、范围(如按照数据值的范围划分分区)等方式进行分区。这样做的好处包括提高查询性能(因为可以只查询特定的分区而不是整个大表)、方便数据的管理(如对过期数据的清理可以针对特定分区进行)等。
- Instance Manager:实例管理。MySQL实例是一个独立的数据库管理环境,包括数据库服务器进程、内存结构和存储的数据等。实例管理服务负责管理MySQL实例的启动、停止、配置等操作。
- Administrator:MySQL管理员。MySQL管理员负责整个MySQL数据库系统的管理工作。这包括用户管理(创建、删除用户,设置用户权限等)、数据库维护(如监控数据库的性能、优化数据库结构、处理数据库故障等)、安全管理(确保数据库的安全性,如设置防火墙规则、防止SQL注入攻击等)等多方面的工作。
- Migration Toolkit:迁移⼯具包。在实际应用中,可能需要将数据从一个数据库系统迁移到MySQL,或者在不同版本的MySQL之间进行数据迁移。MySQL的迁移工具包提供了一系列工具和功能来帮助用户顺利完成这些迁移工作。
NoSQL接口与SQL接口
主要负责接收客⼾端发送的各种SQL语句和命令,并将SQL发送到其他部分,然后把接收到的结果返回给客⼾端。
Parser(语法分析器)
语法分析器的主要作⽤是将客⼾端发来的SQL语句中的关键字和⾃定义字段进⾏提取、解析,最
终将 SQL 语句转换为⼀棵解析树,分析的过程中包含词法分析和语法分析。
- 词法分析,主要是对关键字进⾏提取,⽐如 select/update/delete/create...
- 语法分析,主要判断 SQL 语句是否满⾜语法规则,如果语法错误则异出异常,也就是我们常⻅的ERROR 1064 (42000): You have an error in your SQL syntax。
例如有如下SQL语句, 对应的解析树大致如图所示
select sn, name from student where id = 1;
Optimizer(查询优化器)
通过语法校验的SQL语句将进⼊查询优化器处理阶段,查询优化器会将解析树转化为查询计划,⼀般情况下,⼀条查询可以有很多种执⾏⽅案,查询优化器会根据执⾏计划匹配合适的索引,选择最
佳的执⾏⽅案,最终把确定要执⾏的SQL交给执⾏器调⽤存储引擎API。
Caches & Buffers(缓存)
MySQL的缓存主要的作⽤是为了提升查询的效率,当服务器接收到⼀个 select 查询语句时,会先进⼊缓存查询当前SQL语句在缓存中是否存在,缓存以 key 和 value 的形式存储,key是具体的
SQL语句,value是结果的集合,如果命中缓存,直接返回结果,⽆法命中缓存,则进⼊分析器进⾏正常查询流程。
这⾥需要说明的是,缓存数据对应的数据在被更新之后将会失效,尤其在写多读少的场景中,缓
存会频繁失效与新增,命中率⾮常低,因此MySQL5.6之后服务层缓存功能默认关闭,⽽且在 MySQL8.0中服务层缓存被官⽅删除。
综上了解,SQL语句的执⾏流程如下
存储引擎
存储引擎是处理不同表类型SQL操作的MySQL组件。MySQL服务器采⽤可插拔的存储引擎架构,
在服务器运⾏时可以动态的加载和卸载。
查看当前服务器⽀持哪些存储引擎可以使⽤ show engines 语句, Engine 表⽰:存储引擎的名称, Support :表⽰当前服务器是否⽀持,值分别为: YES 、 NO 和 DEFAULT 分别表⽰,⽀
持、不⽀持和当前设置或默认引擎,如下所⽰:
有关存储引擎的介绍,可以浏览 MySQL 存储引擎-CSDN博客。