本文使用的MySQL版本是8.0
MySQL架构
MySQL架构整体由外部程序和MySQL服务器构成。其中内部服务器分成连接层,服务层,服务管理和公共组件,存储引擎层和文件系统层。
连接层
连接层的作用是处理客户端的连接。
网络端口
一台MySQL服务器可以监听多个网络端口上的客户端连接。MySQL默认开启的是3306这个端口,可以在配置文件中修改添加多个端口。
连接管理线程
通过连接管理器线程处理端口上的客户端连接请求有以下几个场景:
- 对于所有平台:一个管理器线程就能处理所有的TCP/IP连接请求。
- 对于所有平台:可以额外开启一个端口用来管理TCP/IP连接请求。
- 对于Unix:一个管理器线程还可以处理其他的Unix Socket连接请求。
- 对于Windows:一个管理器线程处理Shared-memory方式的连接请求,另一个管理器线程处理Named-pipe方式的连接请求。
当连接管理线程收到请求后,它就会把连接请求转发到执行线程。
执行线程
一个执行线程处理一个连接请求。这里使用了池化技术来减少线程的创建与销毁。
当一个请求要处理时,先从线程池中查找是否有可用的线程:如果没有就创建一个来处理连接,当处理结束后,如果线程池没有满,就放入池中后面在用。通过下面几个系统变量和状态变量能控制连接管理线程。
- 系统变量 thread_cache_size 决定了线程池的大小。默认情况,服务器每次启动时会自动调整这个值,也可以通过选项文件来具体指定,值为0就是禁用缓存池,这样有一个连接就创建执行线程,断开连接后就释放线程。
- 系统变量 thread_stack=N 来调整线程堆栈的大小,为了应对复杂SQL的深层递归。
- 状态变量 Threads_cached 来查看线程数,Threads_created 超过线程数后创建的线程数
连接量管理
- 系统变量 max_connections 可以控制服务器允许同时连接的最大客户端数量(默认是150个)。当达到这个值后,如果还有其他连接,会拒绝其他的请求,并用 状态变量 Connection_errors_max_connections来增量保存连接值。
- 允许管理员额外连接。这就是为什么是151的原因,当非管理员的连接达到最大之后,管理员还能进行连接。
- 主从连接的环境中,从节点的连接数也会计入连接数种。
服务层
服务管理和公共组件
- Backup & Recovery:备份与恢复
备份与恢复是保障 MySQL 数据安全和完整性的关键部分。备份方法有(如物理备份和逻辑备份)、备份工具(如 mysqldump、mysqlhotcopy 和 Percona XtraBackup),以及如何制定和实施有效的备份策略。还包括如何执行数据恢复操作,以便在数据丢失或损坏时快速恢复数据库。
- Security:安全
安全性在 MySQL 管理中至关重要。设置和管理用户权限、身份验证方式、密码策略、加密通信、数据加密等方面的内容。此外,还包括如何审计和监控数据库活动以防止未经授权的访问和潜在的安全威胁。
- Replication:主从复制
主从复制允许数据在多个 MySQL 服务器之间同步,这对于负载均衡、高可用性和数据冗余非常重要。
- Cluster:MySQL集群
MySQL 集群提供了一个高可用性、高可靠性的分布式数据库解决方案。
- Partitioning:表分区
表分区通过将大表分成更小、更易于管理的子表,提高了查询性能和数据管理效率。
- Instance Manager:实例管理
实例管理涉及到对 MySQL 实例的配置、启动、停止、监控和调优。
- Administrator:MySQL管理员
MySQL 管理员需要掌握多方面的知识和技能,包括用户管理、权限控制、安全设置、备份与恢复、性能调优和故障排除等。
- Migration Toolkit:迁移工具包
迁移工具包(如 MySQL Workbench 中的迁移工具)帮助用户将其他数据库系统的数据迁移到 MySQL。
SQL接口
负责收集客户端发过来的各种sql,并将sql发送到解析器,然后把收集到的结果返回到客户端。
解析器
把收到的sql通过词法分析和语法分析进行判断,如果有错误就返回报错。没有错误就发送给优化器。
查询优化器
通过语法校验的sql就进入查询优化器,这里系统会把我们写的sql转换成最优的执行方案,并把最终的sql交给执行器调用存储引擎api。
缓存
需要注意的是5.6之后的版本这个功能默认关闭,8.0后就被官方删除。
这里的缓存存的是key-value值,key:sql语句,value:结果集。
存储引擎
存储引擎是处理不同表类型 SQL 操作的 MySQL 组件。MySQL 服务器采用可插拔的存储引擎架构,在服务器运行时可以动态加载和卸载。
查看引擎
在MySQL客户端下输入
bash
show engines;
# 或者
select * from information_schema.engines;
InnoDB
InnoDB是一款兼顾高可靠性和高性能的通用存储引擎。在MySQL 5.6及其之后,默认的存储引擎是InnoDB。使用CREATE TABLE语句创建表时,在没有修改默认存储引擎或明确指定其他存储引擎时,将创建一个InnoDB的表。
官方文档:MySQL :: MySQL 8.0 Reference Manual :: 17.1 Introduction to InnoDB
特性
根据官网翻译了一下。
优势
安全方面:
- 如果发生意外而崩溃,无论当时数据库发生了什么,都不需要在重启数据库后执行任何特殊操作。InnoDB的崩溃恢复功能会自动完成崩溃之前提交的更改,并撤消崩溃前正在进行但未提交的更改,从而允许我们从中断的地方继续执行。
- 支持数据加密
性能方面:
- 支持行级锁,提高了多用户并发性和性能。
- InnoDB存储引擎维护了自己的缓冲池,在访问数据时会在内存中缓存表和索引数据,以便直接从内存中处理经常使用的数据,从而大幅提升效率。在专用数据库服务器上,通常会将高达80%的物理内存分配给缓冲池。
- InnoDB表优化了基于主键的查询。每个InnoDB表都有一个称为聚簇索引的主键索引,能够通过最少的磁盘I/O完成对主键的查找。
- 当从表中反复查询相同的行时,自适应哈希索引会自动接管这些查询,从而达到类似哈希表的查询效率。
数据方面:
- DML 操作遵循 ACID 模型,事务具有提交、回滚和崩溃恢复功能,可保护用户数据。
- 为了保持数据完整性,InnoDB支持FOREIGN KEY(外键)约束。这意味着在进行插入、更新和删除数据时,InnoDB能够确保相关表之间的一致性。
MyISAM
使用MyISAM存储引擎的表占用空间较小,但由于使用表级锁定,限制了读写操作的性能。因此,它通常用于中小型的Web应用和数据仓库配置中,特别是那些主要是读取或只读的场景。
特性
优势
最大行数为 ( (2^{32})^2 )。
每个MyISAM表最多可以创建64个索引,每个索引最多可以包含16个列。
支持并发插入。
可以通过 CREATE TABLE 语句指定 DATA DIRECTORY=PATH 和 INDEX DIRECTORY=PATH,将数据文件和索引文件放在不同设备的不同目录中,以提高访问速度。
BLOB 和 TEXT 数据类型的列也可以被索引。
索引列中允许使用 NULL 值。
如果在启动时设置了 myisam_recover_options 系统变量,MyISAM表在打开时会进行自查,用于修复未正确关闭的表。
表中 VARCHAR 和 CHAR 列的长度总和最多可达64KB。
UNIQUE 约束的长度没有限制。
存储格式
MyISAM表支持三种不同的存储格式:FIXED(静态/固定格式)、DYNAMIC(动态格式)、以及压缩格式。
压缩格式只能通过 myisampack 实用程序生成,并且是只读格式。
当表中没有 BLOB 或 TEXT 数据类型的列时,可以在使用 CREATE TABLE 或 ALTER TABLE 语句创建或修改表时,结合 ROW_FORMAT 表选项将表格式设置为 FIXED 或 DYNAMIC。
可以使用 myisamchk 工具对已压缩的MyISAM表进行解压操作,命令为 myisamchk --unpack。
静态格式表
静态格式是 MyISAM 表的默认格式,在表不包含可变长度的列(如 VARCHAR、VARBINARY、BLOB 或 TEXT)时使用。每行数据都使用固定数量的字节存储,这使得静态格式在某些方面具有显著的优势:
简单和安全性高:静态格式是最简单和最安全的存储格式之一,最不容易损坏。
读取效率高:由于每行长度固定,根据索引中的行号乘以行长度可以快速计算出行的位置,这使得读取操作非常高效。
存储和重建:崩溃后易于重建,因为每行数据都位于固定位置,不易出现数据碎片化问题。
空间利用:虽然静态格式表需要比动态格式表更多的磁盘空间,但由于数据存储方式的简单性和高效性,通常能够提供更快的性能。
静态格式表还有以下特点:
对于 CHAR 和 VARCHAR 类型的列,使用空格填充到指定的列宽度;对于 BINARY 和 VARBINARY 类型的列,使用 0x00 字节填充到列宽度。
每个允许为 NULL 的列会使用额外的 1 BIT 空间记录当前列是否为空。
由于数据在磁盘上的布局更为简单直接,静态格式表也更容易被操作系统的磁盘缓存所利用,从而提升整体的读取速度。
动态格式表
动态存储格式在 MySQL 中是一种高度灵活的表格存储方式,特别适用于包含可变长度列(如 VARCHAR、VARBINARY、BLOB 或 TEXT)的情况,或者在创建表时明确指定使用 ROW_FORMAT=DYNAMIC 选项。以下是动态格式表的关键特点:
- 动态长度:对于字符串类型的列,长度是动态的,并且每行都有一个标志来指示行的实际长度。当行因更新操作而变长时,数据可能会存储在不连续的空间中,这可能导致数据碎片化。为了优化表的性能和空间利用,可以使用 OPTIMIZE TABLE table_name 或 myisamchk -r 来进行碎片整理。
- NULL 列标志:每个允许为 NULL 的列都会使用一个额外的 1 BIT 空间来记录该列是否为空。
- 位图存储:每行前面有一个位图,用于记录哪些列包含空字符串或零值。如果字符串类型的列长度为零或数字列的值为零,会在位图中标记,而实际上不会保存到磁盘中,从而节省存储空间。
- 磁盘空间利用率高:相比于固定长度表格,动态格式表通常能够更有效地利用磁盘空间,因为它可以按需存储每行的实际数据长度。
- 单独压缩:每行数据和每列数据都可以使用单独的压缩方式,这使得动态格式表在存储和读取大量文本或二进制数据时更加灵活和高效。
在使用动态格式表时,还可以通过优化数据类型选择和压缩方式来进一步提高性能和节省存储空间。比如对于整数列,如果值的范围很小,可以选择更小的数据类型,如将 bigint 类型的列转换为 tinyint 类型,以减少存储空间的使用。
压缩格式表
压缩存储格式在 MySQL 中指的是通过 myisampack 工具生成的只读格式数据表。以下是压缩表的主要特点:
- 磁盘空间效率:压缩表非常有效地利用磁盘空间,最大限度地减少了存储数据所需的空间。这是通过将数据进行压缩来实现的,通常能够显著减少存储需求。
- 适用性:压缩表可以用于处理固定长度或动态长度的行数据,这使得它在不同类型的数据存储需求下都能发挥作用。
- 只读特性:压缩表是只读的,这意味着一旦数据被压缩并生成压缩表,就不能向表中添加新数据或者更新已有的数据。这种只读性质是为了保证数据在压缩后的完整性和一致性。
- 使用与解压:生成压缩表后,可以使用 myisamchk 工具对其进行解压缩,这样可以恢复表的可写状态,从而允许对表进行更新和修改操作。解压缩后的表将回到原始的 MyISAM 表格格式。
压缩存储格式表格通常适用于需要节省大量磁盘空间并且对数据进行只读访问的情况,例如归档数据或静态数据集。
InnoDB和MyISAM的区别
|-----------|--------|-----------|
| 不同点 | InnoDB | MyISAM |
| 事务 | 支持 | 不支持 |
| 外键 | 支持 | 不支持 |
| 自适应hash索引 | 支持 | 不支持 |
| 锁粒度 | 最小到行 | 只能到表 |
| 单表最大限制 | 64TB | 256TB |