MySQL 是什么?它的架构是怎样的?假如让你重新设计,你要怎么做?
MySQL 架构设计
脑子里有 MySQL 8.0 版本的架构设计思路,我在这里岂不是如鱼得水,起飞,起飞,必须起飞。于是我把 MySQL 的架构设计图画了出来,如图 1-1 所示。

图 1-1
看到如此层级的架构设计,分层明确,职责清晰,众人惊呆了!!
但郝纪晓不懈的说到:划分这么多层,有什么意义?该不会是脱裤子放屁多此一举吧。
我心想,难道这是副第一个关卡出现的一个 boss,我看了看他的工牌,上面写着资深架构师——郝纪晓。
系统提示音:新手任务,画出 MySQL 系统架构设计图,并解释每一层以及每层组件的主要作用,让众人理解并清晰认识该架构,让大家按照此架构开发。
好家伙,这个任务难度不大,我自信的给众人解释到:这个数据库名叫 MySQL,至上而下一共分为四层,重点是 Server 服务层和存储引擎层。
客户端由不同语言开发的客户端,Server 层包括连接池、安全管理、线程管理、缓存、SQL 接口、解析器、优化器等,涵盖了 MySQL 的大多数核心功能。
而存储引擎层负责数据的存储的读取。这是一个插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎。
客户端 Client
这是一个 CS 架构,支持各种语言的客户端连接器连接到数据库,比如 Java、C++、JDBC 等。同时也支持 Shell 脚本直接连接。
Server 服务层
这一层至关重要,里面还还会划分为「连接与安全管理」和「SQL 解析和优化」两大模块。
服务层是 MySQL 中的核心组件,负责提供各种数据库操作所需的基本功能,如 SQL 语法处理、事务管理、锁管理等。
连接与安全管理
当客户端发送连接请求时,MySQL 服务器会在连接与安全管理接收请求,分配一个线程来处理该连接,随后进行身份验证。具体的功能如下:
当客户端发起连接请求时,MySQL 会创建一个专用的线程(以操作系统级别的线程实现)来为该客户端服务。
MYSQL 对 TCP 传输过来的账号密码做身份认证、权限获取(例如,是否允许客户端对 world 数据库中的 Country 表执行 SELECT 语句)。验证通过,查询账户拥有的权限,并缓存起来。此链接是一个长链接
对于 TCP 链接,MySQL 采用池化技术,节省了 TCP 链接创建和销毁的成本。
一个客户端请求,必须要分配一个线程专门与客户端进行交互,所以还有个线程池,每一个链接从线程池中获取一个线程,省去了创建和销毁线程的开销。把线程池占满了,再连就报连接满了。
SQL 解析和优化
SQL Interface(SQL 接口,用来接受用户的 SQL 命令,并返回需要的结果。比如 select from 就是调用 SQL Interface。
Parse 解析器
MySQL 解析查询以创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。
Optimizer 优化器
通过语法解析,MySQL 知道你的真实意图了,但你写的 SQL 不一定是高效的。
查询之前会使用查询优化器确定 SQL 语句的执行路径,生成一个执行计划,这个执行计划表明使用哪些索引进行查询。
Caches & Buffers 缓冲区
MySQL 内部维持着一些 Cache 和 Buffer,这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key 缓存,权限缓存等。这个查询缓存可以在 不同客户端之间共享。
查询缓存:当相同的 SQL 查询被多次执行时,可以从查询缓存中直接获取结果,提高性能。由于 MySQL 8.0 中已移除了查询缓存功能,使用者需要自行实现相关功能,如使用 Redis、Memcached 等中间缓存系统。
表缓存:用于存储表的元数据,如表的结构定义。当查询需要表信息时,优先从表缓存中获取,避免磁盘操作。
线程缓存:用于复用服务器的连接线程。当一个连接关闭后,它的线程会被放回线程缓存池中,供新的连接使用。线程池意味着减少了创建和销毁线程的开销。
缓冲池:主要用于 InnoDB 存储引擎,缓冲池管理缓存的数据页,包括数据和索引。当需要访问这些页时,可以直接从缓冲池读取,提高访问速度。
buffer 与 cache 的区别?
简单的说就是,buffer 是写缓存,cache 是读缓存。
存储引擎层
存储引擎层负责存储数据和执行 SQL 语句。MySQL 支持多种存储引擎,每种引擎各有特点,根据实际需求进行选用。当然,只要没有非常明确的特殊需求就不需要更改存储引擎,因为 InnoDB 在大部分场景下都比其他引擎更加适用。
InnoDB:InnoDB 是 MySQL 的默认存储引擎,提供了事务支持、行级锁定、外键约束等功能,主要用于高并发、高可靠性的 OLTP 场景。
MyISAM:MyISAM 通常用于只读数据表,适用于简单查询和全文索引。其不支持事务、行级锁等功能,适用于 OLAP 场景。
Memory:Memory 存储引擎支持哈希和 B 树索引,它将数据存储在内存中,易受到系统断电或宕机等影响,具有较高的写性能但不适用于大规模数据分布。
其他存储引擎:MySQL 还支持如 Archive、NDB Cluster 等其他存储引擎,它们分别适用于存档表、分布式数据库等不同场景。
我们可以在 SQL 命令行中执行 show engines;
来查看当前支持的存储引擎:
文件系统层
文件系统由各操作系统提供,MySQL 将其持久化的数据物理存储在磁盘上,持久化保存数据、索引、binlog、redo log、undo log、error 日志、慢 sql 等;
总结
服务层的连接和安全管理:用户与 MYSQL 服务进行 TCP 链接,校验用户身份,用户权限。
服务层的 SQL 解析和优化:用户写的 SQL 语句会到服务层进行解析,生成语法树。优化 SQL 语句,生成执行计划。
引擎层:真正与磁盘进行交互,对数据进行存储和读取。
最后,我再附上一张在我原来的世界尤其盛行的架构图,与 图 1-1 最大的差别是这次用英文,如图 1-2 所示。

图 1-2
我说完之后,众人纷纷对我称赞。CTO 觉得我的架构设计考虑的太周全了,立马从 T3 晋升为 T4,薪资涨了 20%……
故事还没结束,结构图出来以后,郝纪晓说道:架构图虽然不错,可是还有很多问题并没提及,我们是实干主义,不是写个架构图就能忽悠的。
一条查询、insert、update、delete 语句的执行流程是怎样的?
并发如何控制?
事务如何处理?
Server 层与存储引擎层之间如何保证故障恢复?
binlog、redo log、undo log 都是什么玩意?
磁盘很慢,如何将 读写的随机 I/O 操作变成顺序写保证 数据库性能?
重生之后面对的困难也不简单,这么多问题需要解决,好在我那个世界钻研过 MySQL 技术。我绞尽脑汁的回顾之前学过的 MySQL 技术,希望在这个世界不要就这么 go dead……,还要迎娶白富美......
评论