(一)MySQL全解----MySQL架构

前言

对于程序员,相信MySQL这个词肯定不陌生。MySQL是面试必问的一个知识点,所以MySQL是必须要掌握的核心技术

本专栏是基于MySQL基础知识的进阶和MySQL底层实现的剖析,专栏中涉及到的MySQL基础知识以及基础概念不过多介绍,读者可自行查阅文档

本篇主要介绍MySQL的架构和架构中各层的主要职责

一 MySQL架构体系

开局先上图,MySQL架构体系图如下:
MySQL架构体系图


从上往下,可分为客户端、连接层、服务层、存储引擎层、文件系统层。客户端与MySQL交互时,都遵守这个架构

简单介绍一下每个部分
1 客户端:可以是各类编程语言,如:Python, Java, C/C++, Golang, Rust, PHP …;可以是可视化软件,如:Navicat;也可以是命令行工具。即只要能与MySQL建立连接的都可以被称为是MySQL的客户端
2 连接层:主要是指MySQL的连接池,负责管理所有客户端与MySQL的连接
3 服务层:主要包含系统管理和控制工具、SQL接口、解析器、优化器、缓存和缓冲
4 存储引擎层:指MySQL支持的存储引擎,如InnoDB、MyISAM等
5 文件系统层:数据文件、索引文件、日志文件等各类MySQL运行时所需的文件,位于物理磁盘上

二 连接层

负责管理所有客户端与MySQL的连接,以及连接处理、身份认证、权限控制、安全处理等操作

请求时,如果身份验证通过,即用户名和密码都正确,MySQL还会进行授权操作:查询用户所拥有的权限,并对其授权。当后续执行SQL语句时,会先判断是否具备执行SQL语句的权限,然后再执行SQL语句

一) MySQL的连接池(Connection Pool)

所有客户端与MySQL的连接都需要一个线程去维护,线程的创建和销毁都会消耗系统资源;且系统资源有限,不允许无限的创建线程。所以MySQL使用了连接池,主要是为了复用线程、管理线程以及限制最大连接数

最大连接数通过 max_connections 参数控制。如果超出该值时,后续所有客户端的连接都会被拒绝
当一个客户端连接断开后,处理本次连接的线程不会立马销毁,而是会放入到缓存连接池中,待有新连接时直接复用该线程,避免了创建线程、分配栈空间等操作,提升了性能

二) MySQL使用的通信协议

客户端与MySQL连接时使用的协议,MySQL支持多种通信协议

1 Unix Socket

登录MySQL命令中,如果没有指定-h参数,使用的是socket方式登录,需要用到sock文件(即mysql.sock文件)

2 TCP/IP协议

登录MySQL命令中,如果指定-h参数,使用的是TCP/IP协议

三) MySQL使用的通信类型

一般情况连接数据库都是同步连接;如果要异步,建议使用连接池,排队从连接池获取连接而不是创建新连接

1 同步

同步通信依赖于被调用方,受限于被调用方的性能。即应用线程操作数据库时会阻塞,直到数据库的返回数据
一般只能做到一对一,很难做到一对多的通信

2 异步

异步可以避免应用线程阻塞等待,但是不能节省 SQL执行的时间
异步并发时,为了避免数据混乱,每一个请求都要单独建立一个连接,给MySQL服务端带来压力
异步会提升编码的复杂度,所以一般不建议使用

四) MySQL使用的通信方式

MySQL 使用半双工的通信方式

1 单工

通信时,数据的传输是单向的,即只能A方向B方传输数据

2 半双工

通信时,数据传输是双向的,但同一时间只能有一方在发送数据

3 全双工

通信时,数据传输是双向的,双方可以同时传输数据,互不影响

五) MySQL使用的连接方式

MySQL 既支持短连接,也支持长连接。一般使用的是长连接,一般情况下,连接池中的连接也都是长连接

1 长连接

长连接就是操作执行完成之后,连接继续保持打开状态
长连接可以减少服务端创建和释放连接的消耗,之后访问MySQL可以复用
保持长连接会消耗内存,长时间不活动的连接,MySQL会自动断开

2 短连接

短连接就是操作执行完成之后,马上关闭连接

三 服务层

MySQL大多数核心功能都位于服务层,包括:语法、词法解析和校验、查询优化、查询缓存、内置函数、binlog日志、以及所有跨存储引擎的功能:存储过程、触发器和视图等

一) 系统管理和控制工具(Management Services & Utilities)

负责数据备份、备份恢复、MySQL 复制、安全管理、集群管理等

二) SQL接口(SQL Interface)

主要负责处理客户端的SQL语句
当MySQL接收到客户端发送的SQL命令后,SQL接口会将SQL命令分发给其他组件,然后等待接收执行结果,最后会将结果返回给客户端

SQL接口既是MySQL接收客户端SQL命令的入口,也是MySQL返回数据给客户端的出口

三) 解析器(Parser)

负责解析SQL语句,并校验语法是否合法:是否有执行权限;单/双引号是否闭合;表是否存在;字段是否存在;(表/字段)名字和(表/字段)别名是否有歧义等。如果检测到语法错误,会抛出对应的错误码和信息

解析器会将SQL语句解析并生成一个语法树

四) 优化器(Optimizer)

负责生成执行计划(执行计划可以有多个),并选择其中最优的一个执行计划

MySQL使用基于开销(cost)的优化器,同一条 SQL可以有多种执行方式,但返回的结果相同,使用开销最小的执行计划
MySQL通过复杂的算法尽可能的优化查询效率,使用多种优化策略生成最优的执行计划,可以分为两类:静态优化(编译时优化)、动态优化(运行时优化),如:多表关联查询时,以哪个表的数据作为基准表;多个索引可以使用时,选择哪个索引

看到网上很多资料提到了执行器,MySQL官方并没有列出这个部分,它是一个抽象的概念,实际上不存在。
可以认为维护客户端连接的线程就是执行器,优化器生成执行计划后,维护当前连接的线程根据执行计划去执行SQL,执行SQL实际上是调用存储引擎提供的API

五) 缓存和缓冲(Cache&Buffer)

缓存包括:表缓存,行记录缓存,key缓存,权限缓存等。缓存中主要是行记录缓存:存的是select语句的结果集,就是所谓的查询缓存

缓冲和存储引擎有关,不同的存储引擎缓冲区不同,如:InnoDB的缓冲区是innodb_buffer_pool,而MyISAM是key_buffer

简单展开讲一下有关缓冲的基本知识,后续文章会着重讲这个缓冲:在读取数据时,会先将从磁盘读到的数据对应的页存放在缓冲区;后续对数据进行写操作时,会先查询缓冲区中是否存在要操作数据对应的页,存在则直接对缓冲区的数据页操作;然后会给客户端返回成功;然后MySQL使用后台线程基于Checkpoint机制,将缓冲区中更新的数据页刷写到磁盘

MySQL8.0 已经删除了查询缓存:
a) 命中率不高:SQL语句必须要严格匹配。查询缓存是以key-value形式存储的,key:执行的SQL语句, value:SQL语句执行的结果
b) 可以使用其他中间件作为缓存,如:Redis

MySQL8.0 只是删除了查询缓存,缓存中的其他缓存并没有删除

四 存储引擎层

上面说的服务层包含了MySQL大多数核心功能,而存储引擎层主要负责具体的数据操作

MySQL存在多个不同的存储引擎,因此存储引擎层是插拔式的,即可以根据业务特性,选择不同的存储引擎

为了能够兼容不同的存储引擎,存储引擎的实现规范被定义成API接口,如果想要自己实现存储引擎,只需要实现对应的API接口,同时API接口也屏蔽了不同存储引擎之间的差异,即所有的存储引擎对服务层来说都是一样的操作,服务层不会感知到使用的是哪种存储引擎
所有与底层文件系统(即磁盘)交互的工作都会交给存储引擎层

存储引擎有多种,每种都有各自的优缺点,最常见的存储引擎是MyISAM和InnoDB
以下仅列出常见的三种储存引擎,更多支持的储存引擎请查阅:MySQL8.0支持的储存引擎

一) MyISAM存储引擎

特点:
1) 不支持事务,也不支持外键
2) 支持表级锁
2) 访问速度较快

适合对事务完整性没有要求并以读为主的系统

二) InnoDB存储引擎

MySQL 5.5版本以后默认的存储引擎
特点:
1) 支持事务,支持外键
2) 支持行级锁和表级锁
3) 支持读写并发,写不阻塞读
4) 特殊的索引存放方式,可以减少IO,提升查询效率
5) 比MyISAM存储引擎占用更多的磁盘空间。

适合需要频繁的更新、删除操作,同时还对事务的完整性要求较高,需要实现并发控制的系统

三) MEMORY存储引擎

特点:
1) 数据存储在内存中,访问速度最快,数据库重启或者崩溃,数据会全部丢失
2) 适合做临时表

五 文件系统层

文件系统层主要负责与存储引擎层交互,以及数据的存储与持久化,是指MySQL的数据和日志存储的物理磁盘文件,主要包含日志文件,数据文件,索引文件,配置文件,pid 文件,socket 文件等各类MySQL运行时所需的文件

一) 日志文件

1 错误日志(error log)

记录MySQL启动、运行、关闭时发生的错误的相关信息,默认开启

2 查询日志(general query log)

记录MySQL接收到的每一个查询SQL,默认不开启

3 二进制日志(binary log)

记录对数据的修改操作,并且记录操作发生的时间、执行的时长,默认不开启。MySQL自带的日志
修改操作包括增删改,不会记录select、show等不修改数据库的SQL语句,主要用于数据库恢复和主从复制
简要介绍,后续会详细介绍

4 慢查询日志(slow query log)

log_query_time:默认值10,单位s
记录运行时间超过log_query_time的所有SQL语句以及信息:执行时刻、消耗的时间、执行的用户、连接主机等,默认不开启

5 重做日志(redo log)

记录对数据的修改操作,即MySQL某行表数据的某个字段值从x修改为y,用于MySQL宕机后恢复数据。InnoDB存储引擎独有日志
简要介绍,后续会详细介绍

6 回滚日志(undo log)

记录被修改前的原始数据,用于事务回滚
简要介绍,后续会详细介绍

二) 数据文件

1 库、表信息文件

db.opt文件:保存数据库使用的字符集和验证规则等信息的文件,MySQL8.0不再使用
.frm文件:表结构信息文件,每张表对应一个.frm文件,MySQL8.0不再使用

2 MyISAM存储引擎独有文件

.MYD文件:存放表数据,每张表对应一个.MYD文件
.MYI文件:存放表索引,每张表对应一个.MYI文件
.sdi文件:MySQL8.0使用的表结构信息文件,每张表对应一个sdi文件

3 InnoDB存储引擎独有文件

MySQL8.0不再使用frm文件,表结构信息合并到表空间文件中
ibdata1文件:系统表空间文件,即共享表空间。包含表的元数据、undo log、change buffer和doublewrite buffer。 默认1个,大小12M,路径在数据目录下,大小自动随着数据不断增加,可通过参数innodb_data_file_path配置
.ibd文件:独立表空间文件,只存放表数据、索引、insert buffer bitmap,其余信息依然存放在系统表空间,每张表对应一个.ibd文件
ib_logfile0, ib_logfile1文件:重做日志文件,即redo log file,日志个数默认2个

三) 配置文件

存放MySQL配置信息:my.cnf、my.ini等

四) pid 文件

Unix/Linux 系统中,MySQL启动后,会将自己的进程id入到pid文件

五) socket 文件

Unix/Linux 系统中,MySQL启动后,会产生一个socket文件,客户端可以不使用TCP/IP协议,而使用socket文件来连接 MySQL

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值