MySQL 的架构与组件

MySQL 的逻辑架构图设计图

连接/线程处理:
管理客户端连接/会话[mysql threads]

解析器:
通过检查SQL查询中的每个字符来检查SQL语法,并为每个SQL查询生成  SQL_ID

此外,身份验证检查(用户凭据)将在此阶段发生。

优化程序:
根据存储引擎创建有效的查询执行计划。它将重写一个查询。示例:InnoDB具有共享缓冲区,因此优化器将从中获取预缓存的数据。使用表统计信息优化器将为SQL查询生成执行计划。

授权检查(用户访问权限)将在此阶段发生。

元数据缓存:
缓存对象元数据信息和统计信息。

查询缓存:
来自内存的共享相同查询。如果在查询缓存中找到来自客户端的相同查询,则MySQL服务器从查询缓存中检索结果,而不是再次解析和执行该查询。它是会话的共享缓存,因此可以发送一个客户端生成的结果集以响应另一个客户端发出的相同查询。查询缓存基于SQL_ID.SELECT数据进入视图是使用查询缓存预缓存数据的最佳示例。

密钥缓存:
缓存表索引。在 MySQL 中密钥是索引(在oracle密钥是约束),如果索引大小小,那么它将缓存索引结构和数据叶。如果索引很大,那么它将只缓存索引结构。由MyISAM 使用存储引擎。

存储引擎:
管理物理数据(文件管理)和位置的MySQL组件。存储引擎负责执行SQL语句并从数据文件中获取数据。用作插件,可以从运行MySQL服务器加载/卸载。其中一些引擎如下:

    1. InnoDB:
      • 完全事务性的ACID。
      • 为事务提供REDO和UNDO。
      • 数据存储在表空间中:

      - 多个数据文件
      - 使用InnoDB数据和日志缓冲区的逻辑对象结构

      • 行级锁。
    2. NDB(适用于MySQL群集):
      • 完全事务性和ACID存储引擎。
      • 分配执行数据并使用多个mysqld。
      • NDB为每个NDB引擎使用具有自己的缓冲区的逻辑数据。
      • 为交易提供REDO和UNDO。
      • 行级锁。
    3. MyISAM:
      • 非事务性存储引擎
      • 读取速度快(读多写少)
      • 数据存储在文件中并使用密钥,元数据和查询缓存

      - 表结构的FRM 
      - 表索引的MYI 
      - 表数据的MYD

      • 表级锁定。
    4. Memory:
      • 非事务性存储引擎
      • 除表格元数据和结构外,所有数据都存储在内存中。
      • 表级锁定。
    5. ARCHIVE:
      • 非事务性存储引擎,
      • 存储大量压缩和未编制索引的数据。
      • 允许INSERT,REPLACE 和 SELECT,但不允许 DELETE 或 UPDATE sql操作。
      • 表级锁定。
    6. CSV:
      • 使用逗号分隔值格式在平面文件中存储数据。
      • 需要在MySQL服务器(.frm)中创建表结构

SQL执行

sql 语句查询是首先会去缓存中查找是否有相同语句的记录,没有则会检查 sql 的句法并且生成一个 sql 查询 id,然后是优化查询的 sql 并执行语句,从存储引擎中查找数据。

MySQL连接:

InnoDB 存储引擎:

  • 完全事务性的ACID。
  • 行级锁。
  • 为事务提供REDO和UNDO。
  • 表空间中的数据存储:
    - 多个数据文件
    - 使用InnoDB数据和日志缓冲区的逻辑对象结构
    • 使用共享文件存储对象[数据和索引在同一个文件中]
    • InnoDB数据是逻辑结构的100%,物理存储的数据。
    • InnoDB读取物理数据并构建逻辑结构[Blocks and Rows]
    • 逻辑存储称为TABLESPACE。

InnoDB 存储引擎架构:

表空间:

InnoDB 的存储分为表空间。表空间是与多个数据文件(对象)相关联的逻辑结构。每个表空间都包含页面(块),范围和段

页数(pages): InnoDB的最小数据也称为块。默认页面大小为16kb,页面可以包含一行或多行,具体取决于行大小。

可用页面大小:4kb,8kb,16kb,32kb,64kb 
变量名称:innodb_page_size 
需要在初始化 mysqld 服务器之前进行配置。

范围(extends):   它是一组页面。为了获得更好的 I / O 吞吐量,InnoDB 读取或写入一组页面,即一次一个范围。
对于一组默认页面大小为 16kb 的页面,范围大小最大为 1MB。
Doublewrite 缓冲区一次读取/写入/分配或释放数据到一个范围。

段(Segments):  InnoDB表空间中的文件集合。段中最多使用 4个范围。

InnoDB 组件:

在内存中:

InnoDB 缓冲池:
InnoDB 存储引擎的中央缓冲区。在这个数据缓冲区中,我们加载块和缓存表和索引数据。
- InnoDB 缓存表数据和索引的主存。
- 在专用数据库服务器上调整高达80%的物理内存。
- 跨所有会话的共享缓冲区。
- InnoDB 使用 LRU(最近最少使用)页面替换算法。
- 正在重用的数据始终位于同一内存中。
- 不使用的数据最终将被淘汰。

更改缓冲区:
在内存更改缓冲区是 InnoDB 缓冲池的一部分,在磁盘上,它是系统表空间的一部分,因此即使在数据库重启后索引更改仍保持缓冲。更改缓冲区是一种特殊的数据结构,可以将更改缓存到二级索引页当受影响的页面不在缓冲池中时。

REDO 日志缓冲区:
用于 REDO 日志的缓冲区,保存数据以写入 REDO 日志。定期将数据从 REDO 日志缓冲区刷新到 REDO 日志。将数据从内存刷新到由 innodb_log_at_trx_commit 和 innodb_log_at_timeout 配置选项管理的磁盘。

- 比较大的 REDO 日志缓冲区可以在事务提交之前运行大型事务,而无需将 REDO 日志写入磁盘。
- 变量:
innodb_log_buffer_size(默认为16M)

在磁盘上:

系统表空间:  
除了表数据存储之外,InnoDB 的功能还需要查找表元数据并存储和检索 MVCC 信息以支持 ACID 规范性和事务隔离。它包含 InnoDB 对象的几种类型的信息。

  • 包含:
    表数据页
    表索引页
    数据字典
    MVCC 控制数据(Multi-Version Concurrency Control 多版本并发控制)
    UNDO 空间
    回滚段 Rollback Segments
    双写缓冲区(在后台编写以避免操作系统缓存的页)
    插入缓冲区(对二级索引的更改)

变量:
innodb_data_file_path = / ibdata / ibdata1:10M:autoextend

通过启用innodb_file_per_table(默认)选项,我们可以将每个新创建的表(数据和索引)存储在单独的表空间中。此存储方法的优点是磁盘数据文件中的碎片较少。

常规表空间:
用于存储多个表数据的共享表空间。在 MySQL 5.7.6 中介绍。用户必须使用 CREATE TABLESPACE 语法创建它。TABLESPACE 选项可以与 CREATE TABLE 一起使用来创建表,使用 ALTER TABLE 来移动表到常规表中。

- 内存优于 innodb_file_per_table 存储方法。
- 支持 Antelope 和 Barracuda 文件格式。
- 支持所有行格式和相关功能。
- 可以创建外部数据目录。

InnoDB 数据字典:
系统表空间中的存储区域由内部系统表组成,包含对象[表,索引,列等]的元数据信息

双写缓冲区:
系统表空间中的存储区域,InnoDB在写入数据文件中的正确位置之前从InnoDB缓冲池写入页面。
如果mysqld进程崩溃在页面中间写入,则在崩溃恢复时,InnoDB 可以从 doublewrite 缓冲区中找到页面的良好副本。

变量:inndb_doublewrite(默认启用)

REDO 日志:
用于崩溃恢复。在 mysqld 启动时,InnoDB 执行自动恢复以纠正那些不完整事务写入的数据。在 mysqld 意外关闭之前,那些没有完成数据更新的事务,将在下次mysqld 启动时,自动重做那未完成更新数据文件的事务,即使是在mysqld没有连接的情况下。。它使用 LSN(日志序列号)值。
大量数据更改无法快速写入磁盘,因此它将 REDO ,然后再转到磁盘。

为什么我们需要 REDO 以进行恢复?
让我们举一个例子,用户在 Innodb 缓冲区中更改数据并提交,在写入磁盘之前需要先去的地方。因为在崩溃缓冲区的情况下数据会丢失,这就是我们需要 REDO 日志的原因。

- 在 REDO 时,所有更改都将使用 row_id,旧列值,新列值,session_id 和时间等信息。
- 一个提交完整数据将在磁盘下的数据文件中。
- 变量:
Innodb_log_file_in_group = [ REDO 文件组的数量] 
Innodb_log_file_size = [每个 REDO 文件的大小]

UNDO 表空间和日志:
UNDO 表空间包含一个或多个UNDO日志文件。
UNDO 通过保留活动事务 [MVCC] 的已修改未提交数据来管理一致读取。从该存储区域检索未修改的数据。还原日志也称为回滚段
默认情况下,UNDO 日志是系统表空间的一部分,MySQL 允许将 UNDO 日志存储在单独的表空间中 [在 MySQL 5.6 中引入]。在初始化 mysqld 服务器之前需要配置。

- 当我们配置单独的表空间时,系统表空间中的日志变为非活动状态。
- 需要在初始化 mysqld 服务器之前进行配置,之后无法更改。
- 我们截断 UNDO 日志,但不能删除。
- 变量:
innodb_undo_tablespace:撤销表空间的数量,默认为 0 
innodb_undo_directory:UNDO表空间的位置,默认为 data_dir,大小为 10MB。
innodb_undo_logs:UNDO日志数量,默认值和最大值为“128”

临时表空间:
用于保存和检索临时表和相关对象的已修改未提交数据的存储。介绍 MySQL 5.7.2 并在服务器运行时用于回滚临时表更改。

- 临时表的 UNDO 日志驻留在临时表空间中。
- 在服务器启动时重新创建默认表空间文件 ibtmp1。
- 不习惯崩溃恢复。
- 优势:通过避免临时表和相关对象的 REDO 日志的 IO 来提高性能。
- 变量:
innodb_temp_data_file_path = ibtmp1:12M:autoextend(默认)

原文地址:https://www.cnblogs.com/magic-sea/p/11461125.html