第16章备用存储引擎

目录

16.1设置存储引擎
16.2 MyISAM存储引擎
16.2.1 MyISAM启动选项
16.2.2密钥所需的空间
16.2.3 MyISAM表存储格式
16.2.4 MyISAM表问题
16.3 MEMORY存储引擎
16.4 CSV存储引擎
16.4.1修复和检查CSV表
16.4.2 CSV限制
16.5 ARCHIVE存储引擎
16.6 BLACKHOLE存储引擎
16.7 MERGE存储引擎
16.7.1 MERGE表的优点和缺点
16.7.2 MERGE表问题
16.8 FEDERATED存储引擎
16.8.1联合存储引擎概述
16.8.2如何创建FEDERATED表
16.8.3联合存储引擎注释和提示
16.8.4联合存储引擎资源
16.9示例存储引擎
16.10其他存储引擎
16.11 MySQL存储引擎体系结构概述
16.11.1可插拔存储引擎架构
16.11.2公共数据库服务器层

存储引擎是MySQL组件,用于处理不同表类型的SQL操作。 InnoDB 是默认的和最通用的存储引擎,Oracle建议将其用于表,除了专门的用例。 CREATE TABLE MySQL 8.0中 语句 InnoDB 默认 创建 表。)

MySQL Server使用可插拔存储引擎架构,可以将存储引擎加载到正在运行的MySQL服务器中或从中卸载。

要确定服务器支持哪些存储引擎,请使用该 SHOW ENGINES 语句。 Support 列中 的值 表示是否可以使用引擎。 的值 YES NO DEFAULT 表示发动机可用,不可用,或可用与当前被设置为默认的存储引擎。

MySQL的> SHOW ENGINES\G
*************************** 1。排******************** *******
      引擎:PERFORMANCE_SCHEMA
     支持:是的
     评论:性能架构
交易:NO
          XA:没有
  保存点:没有
*************************** 2.排******************** *******
      引擎:InnoDB
     支持:默认
     注释:支持事务,行级锁定和外键
交易:YES
          XA:是的
  保存点:是
*************************** 3。排******************** *******
      发动机:MRG_MYISAM
     支持:是的
     评论:收集相同的MyISAM表
交易:NO
          XA:没有
  保存点:没有
****************************排******************** *******
      发动机:BLACKHOLE
     支持:是的
     评论:/ dev / null存储引擎(你写的东西都消失了)
交易:NO
          XA:没有
  保存点:没有
****************************排******************** *******
      引擎:MyISAM
     支持:是的
     评论:MyISAM存储引擎
交易:NO
          XA:没有
  保存点:没有
...

本章介绍了专用MySQL存储引擎的用例。 它不 包括 第15章, InnoDB存储引擎 第22章, MySQL NDB Cluster 8.0中 介绍的默认 InnoDB 存储引擎或 NDB 存储引擎 对于高级用户,它还包含可插拔存储引擎体系结构的描述(请参见 第16.11节“MySQL存储引擎体系结构概述” )。

有关商业MySQL Server二进制文件中提供的功能的信息,请参阅 MySQL网站上的MySQL 版本 可用的存储引擎可能取决于您使用的是哪个版本的MySQL。

有关MySQL存储引擎的 常见问题解答 ,请参见 第A.2节“MySQL 8.0 FAQ:存储引擎”

MySQL 8.0支持的存储引擎

您不限于对整个服务器或架构使用相同的存储引擎。 您可以为任何表指定存储引擎。 例如,应用程序可能主要使用 InnoDB 表,一个 CSV 表用于将数据导出到电子表格,一些 MEMORY 表用于临时工作空间。

选择存储引擎

MySQL提供的各种存储引擎在设计时考虑了不同的用例。 下表概述了MySQL提供的一些存储引擎,并在表格后面附有说明。

表16.1存储引擎功能摘要

特征 MyISAM数据 记忆 InnoDB的 档案 导航台
B树索引 没有 没有
备份/时间点恢复 (注1)
群集数据库支持 没有 没有 没有 没有
聚集索引 没有 没有 没有 没有
压缩数据 是(注释2) 没有 没有
数据缓存 没有 N / A 没有
加密数据 是(注3) 是(注3) 是(注4) 是(注3) 是(注3)
外键支持 没有 没有 没有 是(注5)
全文搜索索引 没有 是(注6) 没有 没有
地理空间数据类型支持 没有
地理空间索引支持 没有 是(注7) 没有 没有
哈希索引 没有 不(注8) 没有
索引缓存 N / A 没有
锁定粒度
MVCC 没有 没有 没有 没有
复制支持 (注1) 有限公司(注9)
存储限制 256TB 内存 64TB 没有 384EB
T树索引 没有 没有 没有 没有
交易 没有 没有 没有
更新数据字典的统计信息

笔记:

1.在服务器中实现,而不是在存储引擎中实现。

2.仅在使用压缩行格式时才支持压缩的MyISAM表。 使用带MyISAM的压缩行格式的表是只读的。

3.通过加密功能在服务器中实现。

4.通过加密功能在服务器中实现; 在MySQL 5.7及更高版本中,支持数据静态表空间加密。

5. MySQL Cluster NDB 7.3及更高版本支持外键。

6. MySQL 5.6及更高版本中提供了InnoDB对FULLTEXT索引的支持。

7. MySQL 5.7及更高版本中提供了InnoDB对地理空间索引的支持。

8. InnoDB在内部利用哈希索引来实现其自适应哈希索引功能。

9.请参阅本节后面的讨论。

16.1设置存储引擎

创建新表时,可以通过向 语句 添加 ENGINE 表选项来 指定要使用的存储引擎 CREATE TABLE

- 除非您设置了不同的,否则不需要ENGINE = INNODB
- 默认存储引擎。
CREATE TABLE t1(i INT)ENGINE = INNODB;
- 简单的表定义可以从一个切换到另一个。
CREATE TABLE t2(i INT)ENGINE = CSV;
CREATE TABLE t3(i INT)ENGINE = MEMORY;

省略该 ENGINE 选项时,将使用默认存储引擎。 默认引擎 InnoDB 在MySQL 8.0中。 您可以使用 --default-storage-engine 服务器启动选项 指定默认引擎 ,也可以通过 default-storage-engine my.cnf 配置文件中 设置 选项 来指定默认引擎

您可以通过设置 default_storage_engine 变量 为当前会话设置默认存储引擎

SET default_storage_engine = NDBCLUSTER;

通过在启动时或运行时 设置 ,可以 通过设置 TEMPORARY 创建 的存储引擎 CREATE TEMPORARY TABLE 永久表的引擎分开设置 default_tmp_storage_engine

要将表从一个存储引擎转换为另一个存储引擎,请使用 ALTER TABLE 指示新引擎 语句:

ALTER TABLE t ENGINE = InnoDB;

请参见 第13.1.20节“CREATE TABLE语法” 第13.1.9节“ALTER TABLE语法”

如果您尝试使用未编译但未编译但已停用的存储引擎,则MySQL会使用默认存储引擎创建表。 例如,在复制设置中,您的主服务器可能使用 InnoDB 表来获得最大安全性,但是从服务器使用其他存储引擎来提高速度,但会牺牲持久性或并发性。

默认情况下,无论何时 CREATE TABLE ALTER TABLE 不能使用默认存储引擎 都会生成警告 如果所需的引擎不可用,为了防止出现令人困惑的意外行为,请启用 NO_ENGINE_SUBSTITUTION SQL模式。 如果所需的引擎不可用,则此设置会产生错误而不是警告,并且不会创建或更改该表。 请参见 第5.1.11节“服务器SQL模式”

MySQL可以将表的索引和数据存储在一个或多个其他文件中,具体取决于存储引擎。 表和列定义存储在MySQL数据字典中。 各个存储引擎会创建他们管理的表所需的任何其他文件。 如果表名包含特殊字符,则表文件的名称包含这些字符的编码版本,如 第9.2.3节“标识符到文件名的映射”中所述

16.2 MyISAM存储引擎

MyISAM 基于旧的(不再可用) ISAM 存储引擎,但有许多有用的扩展。

表16.2 MyISAM存储引擎功能

特征 支持
B树索引
备份/时间点恢复 (在服务器中实现,而不是在存储引擎中实现。)
群集数据库支持 没有
聚集索引 没有
压缩数据 是(仅在使用压缩行格式时支持压缩MyISAM表。使用带MyISAM的压缩行格式的表是只读的。)
数据缓存 没有
加密数据 是(通过加密功能在服务器中实现。)
外键支持 没有
全文搜索索引
地理空间数据类型支持
地理空间索引支持
哈希索引 没有
索引缓存
锁定粒度
MVCC 没有
复制支持 (在服务器中实现,而不是在存储引擎中实现。)
存储限制 256TB
T树索引 没有
交易 没有
更新数据字典的统计信息

每个 MyISAM 表都存储在磁盘上的两个文件中。 这些文件的名称以表名开头,并具有指示文件类型的扩展名。 数据文件具有 .MYD MYData )扩展名。 索引文件具有 .MYI MYIndex )扩展名。 表定义存储在MySQL数据字典中。

要明确指定您想要一个 MyISAM 表,请使用 ENGINE 表选项 指示

CREATE TABLE t(i INT)ENGINE = MYISAM;

在MySQL 8.0中,通常需要使用它 ENGINE 来指定 MyISAM 存储引擎,因为 InnoDB 它是默认引擎。

您可以 MyISAM 使用 mysqlcheck 客户端或 myisamchk 实用程序 检查或修复 您还可以 MyISAM 使用 myisampack 压缩 以占用更少的空间。 请参见 第4.5.3节“ mysqlcheck - 表维护程序” 第4.6.4节“ myisamchk - MyISAM表维护实用程序” 第4.6.6节“ myisampack - 生成压缩,只读MyISAM表”

在MySQL 8.0中, MyISAM 存储引擎不提供分区支持。 在以前版本的MySQL中创建的 分区 MyISAM 表不能在MySQL 8.0中使用 有关更多信息,请参见 第23.6.2节“分区与存储引擎相关的限制” 有关升级此类表以便在MySQL 8.0中使用它们的帮助,请参见 第2.11.4节“MySQL 8.0中的更改”

MyISAM 表具有以下特征:

  • 所有数据值首先以低字节存储。 这使得数据机和操作系统独立。 二进制可移植性的唯一要求是机器使用二进制补码有符号整数和IEEE浮点格式。 这些要求在主流机器中广泛使用。 二进制兼容性可能不适用于有时具有特殊处理器的嵌入式系统。

    首先存储低字节数据没有明显的速度损失; 表行中的字节通常是未对齐的,并且按顺序读取未对齐字节所需的处理比按相反顺序处理要多得多。 此外,与其他代码相比,服务器中获取列值的代码不是时间关键。

  • 所有数字键值首先与高字节一起存储,以允许更好的索引压缩。

  • 支持大文件的文件系统和操作系统支持大文件(最大63位文件长度)。

  • 表中有(2 32 2 (1.844E + 19)行的限制 MyISAM

  • 每个 MyISAM 的最大索引数 为64。

    每个索引的最大列数为16。

  • 最大密钥长度为1000个字节。 这也可以通过更改源和重新编译来更改。 对于长度大于250字节的密钥的情况,使用比默认的1024字节更大的密钥块大小。

  • 当按排序顺序插入行时(如使用 AUTO_INCREMENT 列时),将拆分索引树,以便高节点仅包含一个键。 这样可以提高索引树中的空间利用率。

  • AUTO_INCREMENT 支持每个表 对一 列进行 内部处理 MyISAM 自动更新此列 INSERT 以及 UPDATE 操作。 这使得 AUTO_INCREMENT 列更快(至少10%)。 删除后,序列顶部的值不会重复使用。 (当 AUTO_INCREMENT 列被定义为多列索引的最后一列时,会重复使用从序列顶部删除的值。) AUTO_INCREMENT 可以使用 ALTER TABLE myisamchk 重置

  • 将删除与更新和插入混合时,动态大小的行的碎片要小得多。 这是通过自动组合相邻的已删除块并通过扩展块(如果删除下一个块)来完成的。

  • MyISAM 支持并发插入:如果表在数据文件的中间没有空闲块,则可以 INSERT 在其他线程从表中读取的同时 新行放入其中。 由于删除行或使用比其当前内容更多的数据更新动态长度行,可能会发生空闲块。 当所有空闲块用完(填写)时,将来的插入将再次并发。 请参见 第8.11.3节“并发插入”

  • 您可以将数据文件和索引文件放在不同的物理设备上的不同目录中,以便使用 DATA DIRECTORY INDEX DIRECTORY 表选项 获得更快的速度 CREATE TABLE 请参见 第13.1.20节“CREATE TABLE语法”

  • BLOB TEXT 列可以编入索引。

  • NULL 索引列中允许使用值。 每个密钥需要0到1个字节。

  • 每个字符列可以具有不同的字符集。 请参见 第10章, 字符集,排序规则,Unicode

  • MyISAM 索引文件中 有一个标志 ,指示表是否已正确关闭。 如果 使用该 选项 启动 mysqld --myisam-recover-options MyISAM 则会在打开时自动检查表,如果表未正确关闭则会对表进行修复。

  • 如果使用该 --update-state 选项 运行, myisamchk 会将表标记为已选中 myisamchk --fast 仅检查那些没有此标记的表。

  • myisamchk --analyze 存储部分密钥以及整个密钥的统计信息。

  • myisampack 可以打包 BLOB VARCHAR 列。

MyISAM 还支持以下功能:

  • 支持真实 VARCHAR 类型; VARCHAR 列开始与存储在一个或两个字节的长度。

  • 具有 VARCHAR 列的表可以具有固定或动态的行长度。

  • 表中列 VARCHAR CHAR 的长度总和 可能高达64KB。

  • 任意长度限制 UNIQUE

其他资源

16.2.1 MyISAM启动选项

mysqld 的以下选项 可用于更改 MyISAM 的行为 有关其他信息,请参见 第5.1.7节“服务器命令选项”

表16.3 MyISAM选项和变量参考

名称 CMD线 选项文件 系统变量 状态变量 Var范围 动态
bulk_insert_buffer_size
concurrent_insert 全球
DELAY_KEY_WRITE 全球
have_rtree_keys 全球 没有
key_buffer_size的 全球
登录ISAM
的myisam块大小
myisam_data_pointer_size 全球
myisam_max_sort_file_size 全球
myisam_mmap_size 全球 没有
MyISAM数据-恢复选项
- 变量 myisam_recover_options
myisam_recover_options 全球 没有
myisam_repair_threads
myisam_sort_buffer_size
myisam_stats_method
myisam_use_mmap 全球
跳过并发插入
- 变量 concurrent_insert
tmp_table_size的

  • --myisam-recover-options=mode

    设置自动恢复崩溃 MyISAM 的模式

  • --delay-key-write=ALL

    不要在任何 MyISAM 表的 写入之间刷新密钥缓冲区

    注意

    如果执行此操作,则在使用 MyISAM 表时 ,不应 从其他程序(例如来自其他MySQL服务器或使用 myisamchk )访问表。 这样做会导致索引损坏。 使用 --external-locking 并不能消除这种风险。

以下系统变量会影响 MyISAM 的行为 有关其他信息,请参见 第5.1.8节“服务器系统变量”

如果 使用该 选项 启动 mysqld 则会激活自动恢复 --myisam-recover-options 在这种情况下,当服务器打开一个 MyISAM 表时,它会检查表是否标记为崩溃,或者表的打开计数变量是否为0,并且您正在运行禁用外部锁定的服务器。 如果满足以下任一条件,则会发生以下情况:

  • 服务器检查表是否有错误。

  • 如果服务器发现错误,它会尝试进行快速表修复(使用排序而不重新创建数据文件)。

  • 如果修复由于数据文件中的错误而失败(例如,重复键错误),则服务器再次尝试,这次重新创建数据文件。

  • 如果修复仍然失败,服务器将再次尝试使用旧的修复选项方法(逐行写入而不进行排序)。 此方法应该能够修复任何类型的错误并且磁盘空间要求低。

如果恢复将无法从先前完成的语句中恢复所有行,并且您未 FORCE --myisam-recover-options 选项 的值中 指定 ,则 自动修复将在错误日志中中止并显示错误消息:

错误:无法修复表:test.g00pages

如果您指定 FORCE ,则会写入这样的警告:

警告:修复./test/g00pages时找到354行中的344行

如果自动恢复值包括 BACKUP ,则恢复过程将创建具有表单名称的文件 tbl_name-datetime.BAK 您应该有一个 cron 脚本,可以自动将这些文件从数据库目录移动到备份媒体。

16.2.2密钥所需的空间

MyISAM 表使用B树索引。 您可以粗略计算索引文件的大​​小 (key_length+4)/0.67 ,对所有键求和。 这是最糟糕的情况,当所有键按排序顺序插入并且表没有任何压缩键时。

字符串索引是空间压缩的。 如果第一个索引部分是字符串,则它也是前缀压缩的。 如果字符串列具有大量尾随空格或者 VARCHAR 不是总是用于全长 列,则 空间压缩使索引文件小于最坏情况的数字 前缀压缩用于以字符串开头的键。 如果有许多字符串具有相同的前缀,则前缀压缩会有所帮助。

MyISAM 表格中,您还可以通过 PACK_KEYS=1 在创建表格时 指定 表格选项 来为压缩数字添加前缀 数字首先以高字节存储,因此当您有许多具有相同前缀的整数键时,这会有所帮助。

16.2.3 MyISAM表存储格式

MyISAM 支持三种不同的存储格式。 根据您使用的列类型自动选择其中两种(固定格式和动态格式)。 第三种压缩格式只能使用 myisampack 实用程序 创建 (请参见 第4.6.6节“ myisampack - 生成压缩,只读MyISAM表” )。

当您使用 CREATE TABLE ALTER TABLE 用于不具有一个表 BLOB TEXT 列,您可以强制表格形式 FIXED DYNAMIC ROW_FORMAT 表选项。

第13.1.20,“CREATE TABLE语法” ,有关的信息 ROW_FORMAT

您可以 MyISAM 使用 myisamchk 解压缩(解包)压缩 --unpack ; 有关更多信息 请参见 第4.6.4节“ myisamchk - MyISAM表维护实用程序”

16.2.3.1静态(固定长度)表特性

静态格式是 MyISAM 的默认格式 当表不包含可变长度列(它是用来 VARCHAR VARBINARY BLOB ,或 TEXT )。 每行使用固定数量的字节存储。

在三种 MyISAM 存储格式中,静态格式是最简单和最安全的(最少受到损坏)。 它也是磁盘格式中最快的,因为可以轻松地在磁盘上找到数据文件中的行:要根据索引中的行号查找行,请将行号乘以行长度计算行位置。 此外,在扫描表时,每次磁盘读取操作都很容易读取恒定行数。

如果您的计算机在MySQL服务器写入固定格式 MyISAM 文件时 崩溃,则可以证明安全性 在这种情况下, myisamchk 可以轻松确定每行开始和结束的位置,因此它通常可以回收除部分写入行之外的所有行。 MyISAM 始终可以根据数据行重建表索引。

注意

固定长度行格式仅适用于没有 BLOB 没有 TEXT 列的表。 使用带有显式 ROW_FORMAT 子句的 这些列创建表 不会引发错误或警告; 格式规范将被忽略。

静态格式表具有以下特征:

  • CHAR VARCHAR 列是空间填充到指定列的宽度,虽然列类型不被改变。 BINARY VARBINARY 列用 0x00 字节 填充 到列宽。

  • NULL 列需要行中的额外空间来记录它们的值是否为 NULL NULL 列额外增加一位,向上舍入到最近的字节。

  • 很快。

  • 易于缓存。

  • 在崩溃后易于重建,因为行位于固定位置。

  • 除非您删除大量行并希望将可用磁盘空间返回给操作系统,否则无需重组。 为此,请使用 OPTIMIZE TABLE myisamchk -r

  • 通常需要比动态格式表更多的磁盘空间。

  • 使用以下表达式计算静态大小行的预期行长度(以字节为单位):

    行长= 1
                 +(sum of column lengths
                 +(number of NULL columns+ delete_flag+ 7)/ 8
                 +(number of variable-length columns

    delete_flag 对于具有静态行格式的表是1。 静态表在行记录中使用一个位来指示是否已删除该行的标志。 delete_flag 动态表为0,因为该标志存储在动态行标题中。

16.2.3.2动态表特性

用于动态存储格式,如果一个 MyISAM 表包含任何可变长度列( VARCHAR VARBINARY BLOB ,或 TEXT ),或者如果表用所创建的 ROW_FORMAT=DYNAMIC 表的选项。

动态格式比静态格式稍微复杂一些,因为每行都有一个标题,表示它的长度。 由于更新,行变长时,行可能会碎片化(存储在不连续的片段中)。

您可以使用 OPTIMIZE TABLE myisamchk -r 对表进行碎片整理。 如果您在包含一些可变长度列的表中经常访问或更改固定长度的列,则将可变长度列移动到其他表以避免碎片可能是个好主意。

动态格式表具有以下特征:

  • 除了长度小于4的列之外,所有字符串列都是动态的。

  • 每行前面都有一个位图,指示哪些列包含空字符串(对于字符串列)或零(对于数字列)。 这不包括包含 NULL 值的 如果在尾随空格删除后字符串列的长度为零,或者数字列的值为零,则它将在位图中标记,而不会保存到磁盘。 非空字符串保存为长度字节加上字符串内容。

  • NULL 列需要行中的额外空间来记录它们的值是否为 NULL NULL 列额外增加一位,向上舍入到最近的字节。

  • 通常需要的磁盘空间比固定长度表少得多。

  • 每行只使用所需的空间。 但是,如果一行变大,则会将其拆分为所需的多个部分,从而导致行碎片。 例如,如果使用扩展行长度的信息更新行,则该行将变为碎片。 在这种情况下,您可能需要 不时 运行 OPTIMIZE TABLE myisamchk -r 以提高性能。 使用 myisamchk -ei 获取表统计信息。

  • 崩溃后重建静态格式表要比重建更困难,因为行可能会碎片化成许多碎片,并且链接(碎片)可能会丢失。

  • 使用以下表达式计算动态大小行的预期行长度:

    3
    +(number of columns+ 7)/ 8
    +(number of char columns
    +(packed size of numeric columns
    +(length of strings
    +(number of NULL columns+ 7)/ 8
    

    每个链接的罚分为6个字节。 只要更新导致行的放大,就会链接动态行。 每个新链接至少为20个字节,因此下一个放大可能在同一个链接中。 如果不是,则创建另一个链接。 您可以使用 myisamchk -ed 找到链接数 可以使用 OPTIMIZE TABLE myisamchk -r 删除所有链接

16.2.3.3压缩表特性

压缩存储格式是使用 myisampack 工具 生成的只读格式 压缩表可以使用 myisamchk 解压缩

压缩表具有以下特征:

  • 压缩表占用的磁盘空间非常小。 这可以最大限度地减少磁盘使用,这在使用慢速磁盘(如CD-ROM)时很有用。

  • 每行都是单独压缩的,因此访问开销非常小。 行的标头占用一到三个字节,具体取决于表中的最大行。 每列的压缩方式不同。 每列通常有不同的霍夫曼树。 一些压缩类型是:

    • 后缀空间压缩。

    • 前缀空间压缩。

    • 使用一位存储值为零的数字。

    • 如果整数列中的值具有较小的范围,则使用尽可能小的类型存储该列。 例如,如果 BIGINT 列(八个字节)的 TINYINT 所有值都在 -128 to 的范围内,则 可以将其存储为 列(一个字节) 127

    • 如果列只有一小组可能的值,则数据类型将转换为 ENUM

    • 列可以使用前述压缩类型的任何组合。

  • 可用于固定长度或动态长度的行。

注意

虽然压缩表是只读的,因此您无法在表中更新或添加行,但DDL(数据定义语言)操作仍然有效。 例如,您仍可以使用 DROP 删除表并 TRUNCATE TABLE 清空表。

16.2.4 MyISAM表问题

MySQL用于存储数据的文件格式已经过广泛测试,但始终存在可能导致数据库表损坏的情况。 以下讨论描述了如何发生这种情况以及如何处理它。

16.2.4.1损坏的MyISAM表

即使 MyISAM 表格格式非常可靠(SQL语句所做的所有更改都是在语句返回之前写入的),如果发生以下任何事件,您仍然可能会损坏表格:

  • mysqld的 进程在写中间被杀害。

  • 发生意外的计算机关闭(例如,计算机已关闭)。

  • 硬件故障。

  • 您正在使用外部程序(例如 myisamchk )来修改服务器同时修改的表。

  • MySQL或 MyISAM 代码 中的软件错误

腐败表的典型症状是:

  • 从表中选择数据时出现以下错误:

    表的密钥文件不正确:'...'。尝试修复它
    
  • 查询在表中找不到行或返回不完整的结果。

您可以 MyISAM 使用该 CHECK TABLE 语句 检查 的运行状况 ,并 使用该 表修复损坏的 MyISAM REPAIR TABLE mysqld 未运行时,您还可以使用 myisamchk 命令 检查或修复表 请参见 第13.7.3.2节“检查表语法” 第13.7.3.5节“修复表语法” 第4.6.4节“ myisamchk - MyISAM表维护实用程序”

如果您的表经常损坏,您应该尝试确定为什么会发生这种情况。 最重要的是要知道表是否因服务器崩溃而损坏。 您可以通过 restarted mysqld 在错误日志中 查找最近的 消息来 轻松验证这一点 如果存在此类消息,则表损坏很可能是服务器死亡的结果。 否则,在正常操作期间可能发生损坏。 这是一个错误。 您应该尝试创建一个可重现的测试用例来演示该问题。 请参见 第B.4.3.3节“如果MySQL不断崩溃该怎么办” ,以及 第29.5节“调试和移植MySQL”

16.2.4.2表格未正确关闭的问题

每个 MyISAM 索引文件( .MYI 文件)在标头中都有一个计数器,可用于检查表是否已正确关闭。 如果你从下面的警告 CHECK TABLE myisamchk的 ,这意味着这个计数器已经不同步:

客户正在使用或未正确关闭表

此警告并不一定意味着表已损坏,但您至少应检查该表。

该计数器的工作原理如下:

  • 第一次在MySQL中更新表时,索引文件头中的计数器会递增。

  • 在进一步更新期间,计数器不会更改。

  • 当表的最后一个实例关闭时(因为 FLUSH TABLES 执行 操作或者因为表缓存中没有空间),如果表已在任何时候更新,则计数器会递减。

  • 当您修复表格或检查表格并且发现它没有问题时,计数器将重置为零。

  • 为了避免与可能检查表的其他进程交互的问题,如果计数器为零,则计数器不会在关闭时递减。

换句话说,只有在以下条件下,计数器才会变得不正确:

16.3 MEMORY存储引擎

MEMORY 存储引擎(以前称为 HEAP )创建具有存储在存储器中的内容的专用的表。 由于数据易受崩溃,硬件问题或断电影响,因此只能将这些表用作临时工作区或从其他表中提取数据的只读缓存。

表16.4 MEMORY存储引擎功能

特征 支持
B树索引
备份/时间点恢复 (在服务器中实现,而不是在存储引擎中实现。)
群集数据库支持 没有
聚集索引 没有
压缩数据 没有
数据缓存 N / A
加密数据 是(通过加密功能在服务器中实现。)
外键支持 没有
全文搜索索引 没有
地理空间数据类型支持 没有
地理空间索引支持 没有
哈希索引
索引缓存 N / A
锁定粒度
MVCC 没有
复制支持 (在服务器中实现,而不是在存储引擎中实现。) 有限(请参阅本节后面的讨论。)
存储限制 内存
T树索引 没有
交易 没有
更新数据字典的统计信息

何时使用MEMORY或NDB群集

希望将使用 MEMORY 存储引擎的 应用程序部署到 重要,高可用或频繁更新的数据的开发人员应考虑NDB Cluster是否是更好的选择。 MEMORY 引擎的 典型用例 涉及以下特征:

  • 涉及临时,非关键数据(如会话管理或缓存)的操作。 当MySQL服务器暂停或重新启动时, MEMORY 表中 的数据 将丢失。

  • 内存存储,可实现快速访问和低延迟。 数据卷可以完全适合内存,而不会导致操作系统更换虚拟内存页。

  • 只读或主要读取数据访问模式(有限更新)。

NDB Cluster提供 MEMORY 与具有更高性能级别 引擎 相同的功能 ,并提供以下不具备的其他功能 MEMORY

  • 行级锁定和多线程操作,可在客户端之间实现低争用。

  • 即使包含写入的语句混合,也具有可伸缩性。

  • 用于数据持久性的可选磁盘备份操作。

  • 无共享架构和多主机操作,无单点故障,可实现99.999%的可用性。

  • 跨节点自动分配数据; 应用程序开发人员无需制作自定义分片或分区解决方案。

  • 支持不支持的可变长度数据类型(包括 BLOB TEXT MEMORY

分区

MEMORY 表格无法分区。

性能特点

MEMORY 在处理更新时,单线程执行和表锁开销导致的争用会限制性能。 这会在负载增加时限制可伸缩性,特别是对于包含写入的语句混合。

尽管对 MEMORY 进行了内存处理 ,但它们不一定比 InnoDB 繁忙服务器上的表,通用查询或读/写工作负载 更快 特别是,执行更新所涉及的表锁定可能会减慢 MEMORY 来自多个会话 表的 并发使用

根据对 MEMORY 执行的查询类型 ,您可以创建索引作为默认哈希数据结构(用于基于唯一键查找单个值)或通用B树数据结构(用于各种类型)涉及平等,不等式或范围运算符的查询,例如小于或大于)。 以下部分说明了创建这两种索引的语法。 常见的性能问题是在B树索引更有效的工作负载中使用默认哈希索引。

记忆表的特征

MEMORY 存储引擎不磁盘上创建任何文件。 表定义存储在MySQL数据字典中。

MEMORY 表具有以下特征:

  • MEMORY 空间以 小块分配。 表对插入使用100%动态哈希。 不需要溢出区域或额外的密钥空间。 免费列表不需要额外的空间。 已删除的行将放入链接列表中,并在向表中插入新数据时重复使用。 MEMORY 表也​​没有通常与散列表中的删除和插入相关的问题。

  • MEMORY 表使用固定长度的行存储格式。 可变长度类型,例如 VARCHAR 使用固定长度存储。

  • MEMORY 表不能包含 BLOB TEXT 列。

  • MEMORY 包括对 AUTO_INCREMENT 列的 支持

  • TEMPORARY MEMORY 表格在所有客户端之间共享,就像任何其他非 TEMPORARY 表格一样。

MEMORY表的DDL操作

要创建 MEMORY 表,请在语句 ENGINE=MEMORY 指定子句 CREATE TABLE

CREATE TABLE t(i INT)ENGINE = MEMORY;

如引擎名称所示, MEMORY 表存储在内存中。 它们默认使用哈希索引,这使得它们对于单值查找非常快,并且对于创建临时表非常有用。 但是,当服务器关闭时,存储在 MEMORY 表中的 所有行都将 丢失。 表本身继续存在,因为它们的定义存储在MySQL数据字典中,但是当服务器重新启动时它们是空的。

此示例显示了如何创建,使用和删除 MEMORY 表:

mysql> 
mysql> 
mysql>CREATE TABLE test ENGINE=MEMORY
           SELECT ip,SUM(downloads) AS down
           FROM log_table GROUP BY ip;SELECT COUNT(ip),AVG(down) FROM test;DROP TABLE test;

MEMORY 的最大大小 max_heap_table_size 系统变量的 限制, 系统变量的默认值为16MB。 要对 MEMORY 强制执行不同的大小限制 ,请更改此变量的值。 在效果的值 CREATE TABLE ,或随后的 ALTER TABLE TRUNCATE TABLE ,是用于表的寿命值。 服务器重新启动还会将现有 MEMORY 的最大大小设置 为全局 max_heap_table_size 值。 您可以设置各个表的大小,如本节后面所述。

索引

MEMORY 存储引擎支持 HASH BTREE 索引。 您可以通过添加 USING 如下所示 子句为 给定索引指定一个或另一个

CREATE TABLE查找
    (id INT,INDEX USING HASH(id))
    ENGINE = MEMORY;
CREATE TABLE查找
    (id INT,索引使用BTREE(id))
    ENGINE = MEMORY;

有关B树和哈希索引的一般特性,请参见 第8.3.1节“MySQL如何使用索引”

MEMORY 每个表最多可以有64个索引,每个索引有16列,最大密钥长度为3072字节。

如果 MEMORY 表哈希索引具有高度密钥重复(许多索引条目包含相同的值),则对表影响键值和所有删除的更新会明显变慢。 这种减速程度与重复程度成正比(或与指数基数成反比)。 您可以使用 BTREE 索引来避免此问题。

MEMORY 表可以有非唯一键。 (这是哈希索引实现的一个不常见的功能。)

索引的列可以包含 NULL 值。

用户创建的和临时表

MEMORY 表内容存储在内存中,该内存是 MEMORY 表与服务器在处理查询时动态创建的内部临时表共享 的属性 但是,这两种表的不同之处在于 MEMORY 表不受存储转换的影响,而内部临时表是:

加载数据中

MEMORY 在MySQL服务器启动时 填充 表,可以使用该 --init-file 选项。 例如,您可以将诸如 INSERT INTO ... SELECT 或之类的 语句 LOAD DATA 放入此文件中以从持久数据源加载表。 请参见 第5.1.7节“服务器命令选项” 第13.2.7节“LOAD DATA语法”

内存表和复制

服务器的 MEMORY 表在关闭并重新启动时变为空。 如果服务器是复制主服务器,则其从属服务器不知道这些表已变为空,因此如果从从属服务器上的表中选择数据,则会看到过时的内容。 要同步主 MEMORY 和从 表,当 MEMORY 自启动以来第一次使用表时,会将 DELETE 语句写入主服务器的二进制日志,以清空从服务器上的表。 在主服务器重新启动和第一次使用表之间的间隔期间,从服务器仍然在表中过期数据。 要避免此间隔,当直接查询从站可能返回过时数据时,请使用 --init-file MEMORY 在启动时 填充 主服务器上 表的 选项

管理内存使用

服务器需要足够的内存来维护所有 MEMORY 正在使用的表。

如果从 MEMORY 表中 删除单个行,则不会回收内存 仅在删除整个表时才回收内存。 以前用于已删除行的内存将重新用于同一表中的新行。 MEMORY 在不再需要其内容时 释放 使用的所有内存 ,请执行 DELETE TRUNCATE TABLE 删除所有行,或者完全删除表 DROP TABLE 要释放已删除行使用的内存,请使用 ALTER TABLE ENGINE=MEMORY 强制表重建。

MEMORY 使用以下表达式计算表中 一行所需的内存

SUM_OVER_ALL_BTREE_KEYS(max_length_of_key+ sizeof(char *)* 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char *)* 2)
+ ALIGN(length_of_row+ 1,sizeof(char *))

ALIGN() 表示使行长度成为 char 指针大小 的精确倍数的向上舍入因子 sizeof(char*) 在32位计算机上是4,在64位计算机上是8。

如前所述, max_heap_table_size 系统变量设置 MEMORY 的最大大小限制 要控制各个表的最大大小,请在创建每个表之前设置此变量的会话值。 (不要更改全局 max_heap_table_size 值,除非您打算将值用于 MEMORY 所有客户端创建的 MEMORY 。)以下示例创建两个 表,最大大小分别为1MB和2MB:

MySQL的> SET max_heap_table_size = 1024*1024;
查询正常,0行受影响(0.00秒)

MySQL的> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
查询OK,0行受影响(0.01秒)

MySQL的> SET max_heap_table_size = 1024*1024*2;
查询正常,0行受影响(0.00秒)

MySQL的> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
查询正常,0行受影响(0.00秒)

max_heap_table_size 如果服务器重新启动,则 两个表都将恢复为服务器的全局 值。

您还可以在 MAX_ROWS 表的 CREATE TABLE 语句中 指定 表选项, MEMORY 以提供有关计划存储在其中的行数的提示。 这不会使表增长超出 max_heap_table_size 值,这仍然作为最大表大小的约束。 为了最大限度地灵活使用 MAX_ROWS ,请 max_heap_table_size 至少 设置 您希望每个 MEMORY 表能够增长的值。

其他资源

有关 MEMORY 存储引擎的 论坛, 请访问 https://forums.mysql.com/list.php?92

16.4 CSV存储引擎

CSV 使用逗号分隔值格式的文本文件存储引擎存储数据。

CSV 存储引擎总是被编译到MySQL服务器。

要检查 CSV 引擎 的源代码 ,请查看 storage/csv MySQL源代码分发 目录。

创建 CSV 表时,服务器会创建一个纯文本数据文件,其名称以表名开头并具有 .CSV 扩展名。 将数据存储到表中时,存储引擎会以逗号分隔值格式将其保存到数据文件中。

MySQL的> CREATE TABLE test (i INT NOT NULL, c CHAR(10) NOT NULL)
       ENGINE = CSV;
查询正常,0行受影响(0.06秒)

MySQL的> INSERT INTO test VALUES(1,'record one'),(2,'record two');
查询OK,2行受影响(0.05秒)
记录:2个重复:0个警告:0

MySQL的> SELECT * FROM test;
+  -  + ------------ +
| 我| c |
+  -  + ------------ +
| 1 | 记录一个|
| 2 | 记录两个|
+  -  + ------------ +
2行(0.00秒)

创建 CSV 表还会创建相应的元文件,该元文件存储表的状态和表中存在的行数。 此文件的名称与具有扩展名的表的名称相同 CSM

如果检查 test.CSV 通过执行前面的语句创建的数据库目录中 文件,其内容应如下所示:

“1”,“记录一”
“2”,“记录2”

这种格式可以通过电子表格应用程序(如Microsoft Excel或StarOffice Calc)读取甚至编写。

16.4.1修复和检查CSV表

CSV 存储引擎支持 CHECK TABLE REPAIR TABLE 语句来验证,如果可能,修复损坏的 CSV 表。

运行 CHECK TABLE 语句时, CSV 将通过查找正确的字段分隔符,转义字段(匹配或缺少引号),与表定义相比的正确字段数以及是否存在相应的 CSV 文件来检查文件的有效性 发现的第一个无效行将报告错误。 检查有效表会产生如下所示的输出:

MySQL的> CHECK TABLE csvtest;
+ -------------- + ------- + ---------- + ---------- +
| 表| Op | Msg_type | Msg_text |
+ -------------- + ------- + ---------- + ---------- +
| test.csvtest | 检查| 状态| 好的
+ -------------- + ------- + ---------- + ---------- +

检查损坏的表会返回错误:

MySQL的> CHECK TABLE csvtest;
+ -------------- + ------- + ---------- + ---------- +
| 表| Op | Msg_type | Msg_text |
+ -------------- + ------- + ---------- + ---------- +
| test.csvtest | 检查| 错误| 腐败|
+ -------------- + ------- + ---------- + ---------- +

如果检查失败,表将被标记为崩溃(损坏)。 一旦表被标记为已损坏,它将在您下次运行 CHECK TABLE 或执行 SELECT 语句 时自动修复 运行时将显示相应的损坏状态和新状态 CHECK TABLE

MySQL的> CHECK TABLE csvtest;
+ -------------- + ------- + ---------- + --------------- ------------- +
| 表| Op | Msg_type | Msg_text |
+ -------------- + ------- + ---------- + --------------- ------------- +
| test.csvtest | 检查| 警告| 表被标记为崩溃|
| test.csvtest | 检查| 状态| 好的
+ -------------- + ------- + ---------- + --------------- ------------- +

要修复表,请使用 REPAIR TABLE 从现有 CSV 数据中 复制尽可能多的有效行 ,然后使用 CSV 恢复的行 替换现有 文件。 超出损坏数据的任何行都将丢失。

MySQL的> REPAIR TABLE csvtest;
+ -------------- + -------- + ---------- + ---------- +
| 表| Op | Msg_type | Msg_text |
+ -------------- + -------- + ---------- + ---------- +
| test.csvtest | 修理| 状态| 好的
+ -------------- + -------- + ---------- + ---------- +
警告

在修复期间,只将 CSV 文件中 的行 直到第一个损坏的行复制到新表。 从第一个损坏的行到表的末尾的所有其他行都被删除,甚至是有效的行。

16.4.2 CSV限制

CSV 存储引擎不支持索引。

CSV 存储引擎不支持分区。

使用 CSV 存储引擎 创建的所有表 必须具有 NOT NULL 所有列 属性。

16.5 ARCHIVE存储引擎

ARCHIVE 存储引擎产生大量未索引数据存储在一个非常小的足迹专用表。

表16.5 ARCHIVE存储引擎功能

特征 支持
B树索引 没有
备份/时间点恢复 (在服务器中实现,而不是在存储引擎中实现。)
群集数据库支持 没有
聚集索引 没有
压缩数据
数据缓存 没有
加密数据 是(通过加密功能在服务器中实现。)
外键支持 没有
全文搜索索引 没有
地理空间数据类型支持
地理空间索引支持 没有
哈希索引 没有
索引缓存 没有
锁定粒度
MVCC 没有
复制支持 (在服务器中实现,而不是在存储引擎中实现。)
存储限制 没有
T树索引 没有
交易 没有
更新数据字典的统计信息

ARCHIVE 存储引擎包含在MySQL二进制分发。 要从源代码构建MySQL,要启用此存储引擎,请 使用该 选项 调用 CMake -DWITH_ARCHIVE_STORAGE_ENGINE

要检查 ARCHIVE 引擎 的源代码 ,请查看 storage/archive MySQL源代码分发 目录。

您可以 ARCHIVE 使用该 SHOW ENGINES 语句 检查 存储引擎是否可用

创建 ARCHIVE 表时,存储引擎会创建名称以表名开头的文件。 数据文件的扩展名为 .ARZ .ARN 优化过程中操作文件可能会出现。

ARCHIVE 引擎支持 INSERT REPLACE SELECT ,而不是 DELETE UPDATE 它支持 ORDER BY 操作, BLOB 列和空间数据类型(请参见 第11.5.1节“空间数据类型” )。 不支持地理空间参考系统。 ARCHIVE 发动机采用了行级锁。

ARCHIVE 引擎支持 AUTO_INCREMENT column属性。 AUTO_INCREMENT 列可以具有唯一或非唯一索引。 尝试在任何其他列上创建索引会导致错误。 ARCHIVE 引擎还支持 语句中 AUTO_INCREMENT table选项, CREATE TABLE 以指定新表的初始序列值或分别重置现有表的序列值。

ARCHIVE 不支持将值插入 AUTO_INCREMENT 小于当前最大列值的列。 尝试这样做会导致 ER_DUP_KEY 错误。

ARCHIVE 引擎将忽略 BLOB 列,如果没有要求,并扫描他们过去在阅读它们。

ARCHIVE 存储引擎不支持分区。

存储: 行在插入时被压缩。 ARCHIVE 引擎使用 zlib 无损数据压缩(参见 http://www.zlib.net/ )。 您可以使用它 OPTIMIZE TABLE 来分析表格并将其打包成较小的格式(出于使用原因 OPTIMIZE TABLE ,请参阅本节后面的内容)。 引擎也支持 CHECK TABLE 有几种类型的插入使用:

  • 一个 INSERT 声明只是推行成一个压缩缓冲,并且缓冲刷新是必要的。 插入缓冲区受锁保护。 A SELECT 强制发生冲洗。

  • 批量插入只有在完成后才可见,除非同时出现其他插入,在这种情况下可以部分看到。 SELECT 除非在装载时发生正常插入,否则 A 永远不会导致批量插入的冲洗。

检索 :在检索时,行按需解压缩; 没有行缓存。 一个 SELECT 操作执行一个完整的表扫描:当 SELECT 发生时,它发现有多少行是目前可用的和读取的行数。 SELECT 以一致的读数执行。 请注意, SELECT 插入过程 中的大量 语句会导致压缩性能下降,除非仅使用批量插入。 要获得更好的压缩效果,可以使用 OPTIMIZE TABLE REPAIR TABLE ARCHIVE 报告的表中 的行数 SHOW TABLE STATUS 始终准确。 请参见 第13.7.3.4节“OPTIMIZE TABLE语法” 第13.7.3.5节“修复表语法” ,以及 第13.7.6.36节“显示表状态语法”

其他资源

16.6 BLACKHOLE存储引擎

BLACKHOLE 存储引擎作为一个 黑洞 ,它接受的数据,但它扔了出去,不存储。 检索始终返回空结果:

MySQL的> CREATE TABLE test(i INT, c CHAR(10)) ENGINE = BLACKHOLE;
查询正常,0行受影响(0.03秒)

MySQL的> INSERT INTO test VALUES(1,'record one'),(2,'record two');
查询正常,2行受影响(0.00秒)
记录:2个重复:0个警告:0

MySQL的> SELECT * FROM test;
空集(0.00秒)

要从 BLACKHOLE 源代码构建MySQL, 要启用 存储引擎,请 使用该 选项 调用 CMake -DWITH_BLACKHOLE_STORAGE_ENGINE

要检查 BLACKHOLE 引擎 的源代码 ,请查看 sql MySQL源代码分发 目录。

创建 BLACKHOLE 表时,服务器在全局数据字典中创建表定义。 没有与该表关联的文件。

BLACKHOLE 存储引擎支持所有类型的索引。 也就是说,您可以在表定义中包含索引声明。

BLACKHOLE 存储引擎不支持分区。

您可以 BLACKHOLE 使用该 SHOW ENGINES 语句 检查 存储引擎是否可用

插入 BLACKHOLE 表中不会存储任何数据,但如果启用了基于语句的二进制日志记录,则会记录SQL语句并将其复制到从属服务器。 这可用作转发器或过滤器机制。

假设您的应用程序需要从属端过滤规则,但首先将所有二进制日志数据传输到从属服务器会导致流量过大。 在这种情况下,可以在主主机上设置 其默认存储引擎 虚拟 从属进程, BLACKHOLE 如下所示:

图16.1使用BLACKHOLE进行过滤的复制

使用BLACKHOLE进行复制进行过滤

主机写入其二进制日志。 虚设 的mysqld 过程是一个从机,施加的所需组合 replicate-do-* replicate-ignore-* 规则,并写入它自己的新的,过滤二进制日志。 (请参见 第17.1.6节“复制和二进制日志记录选项和变量” 。)此过滤日志将提供给从站。

虚拟进程实际上并不存储任何数据,因此 在复制主机上 运行额外的 mysqld 进程会 产生很少的处理开销 可以使用其他复制从站重复此类型的设置。

INSERT BLACKHOLE 表的 触发器 按预期工作。 但是,因为该 BLACKHOLE 表实际上并不存储任何数据, UPDATE 并且 DELETE 未激活触发器: FOR EACH ROW 触发器定义中 子句不适用,因为没有行。

BLACKHOLE 存储引擎的 其他可能用途 包括:

  • 验证转储文件语法。

  • 通过使用 BLACKHOLE 启用和不启用二进制日志记录的 性能比较来测量二进制日志记录的开销

  • BLACKHOLE 本质上是一个 无操作 ”的 存储引擎,因此可用于查找与存储引擎本身无关的性能瓶颈。

BLACKHOLE 发动机是交易感知的,在这个意义上,提交的事务都写入二进制日志和回滚事务都没有。

黑洞引擎和自动增量列

Blackhole引擎是一种无操作引擎。 使用Blackhole在桌面上执行的任何操作都不起作用。 在考虑自动递增的主键列的行为时,应该记住这一点。 引擎不会自动增加字段值,也不会保留自动增量字段状态。 这对复制具有重要意义。

请考虑以下所有三个条件适用的复制方案:

  1. 在主服务器上有一个黑洞表,其中一个自动增量字段是主键。

  2. 在从属服务器上存在相同的表但使用MyISAM引擎。

  3. 插入将在主表中执行,而无需在 INSERT 语句本身或通过使用 SET INSERT_ID 语句 显式设置自动增量值

在这种情况下,复制将失败,主键列上出现重复的条目错误。

在基于语句的复制中, INSERT_ID 上下文事件中 的值 将始终相同。 因此,由于尝试插入具有主键列的重复值的行,复制将失败。

在基于行的复制中,引擎为行返回的值对于每个插入始终是相同的。 这将导致从服务器尝试使用主键列的相同值重播两个插入日志条目,因此复制将失败。

列过滤

使用基于行的复制时,( binlog_format=ROW )时,支持表中缺少最后一列的从站,如 第17.4.1.9节“使用主站和从站上的不同表定义进行复制” 中所述

此过滤在从属端工作,即在过滤掉列之前将列复制到从属。 至少有两种情况不希望将列复制到从属:

  1. 如果数据是机密的,那么从服务器就不应该访问它。

  2. 如果主站有许多从站,则在发送到从站之前进行过滤可能会减少网络流量。

使用 BLACKHOLE 引擎 可以实现主列过滤 这是通过类似于如何实现主表过滤的方式执行的 - 通过使用 BLACKHOLE 引擎和 --replicate-do-table --replicate-ignore-table 选项。

主人的设置是:

CREATE TABLE t1(public_col_1,...,public_col_N,
                 secret_col_1,...,secret_col_M)ENGINE = MyISAM;

可信奴隶的设置是:

CREATE TABLE t1(public_col_1,...,public_col_N)ENGINE = BLACKHOLE;

不受信任的从站的设置是:

CREATE TABLE t1(public_col_1,...,public_col_N)ENGINE = MyISAM;

16.7 MERGE存储引擎

MERGE 存储引擎,也被称为 MRG_MyISAM 发动机,是相同的集合 MyISAM 可被用作一个表。 相同 表示所有表具有相同的列数据类型和索引信息。 您不能合并 MyISAM 以不同顺序列出列的表,相应列中没有完全相同的数据类型,或者索引的顺序不同。 但是, MyISAM 可以使用 myisampack 压缩 任何或所有 请参见 第4.6.6节“ myisampack - 生成压缩,只读MyISAM表” 这些表之间的差异无关紧要:

  • 相应列和索引的名称可以不同。

  • 表,列和索引的注释可以不同。

  • 表的选项,如 AVG_ROW_LENGTH MAX_ROWS PACK_KEYS 可以不同。

MERGE 的替代方法 是分区表,它将单个表的分区存储在单独的文件中,并使某些操作能够更有效地执行。 有关更多信息,请参见 第23章, 分区

创建 MERGE 表时,MySQL会 .MRG 在磁盘上 创建一个 文件,其中包含 MyISAM 应作为一个表使用 的基础 的名称 表的表格格式 MERGE 存储在MySQL数据字典中。 基础表不必与 MERGE 位于同一数据库 中。

您可以使用 SELECT DELETE UPDATE ,和 INSERT MERGE 表。 你必须有 SELECT DELETE UPDATE 特权 MyISAM ,你映射到表的 MERGE 表。

注意

MERGE 的使用 带来以下安全问题:如果用户有权访问 MyISAM t ,则该用户可以创建 访问 MERGE 但是,如果 随后撤消 了用户的权限 ,则用户可以 通过此 方式继续访问 m t t t m

使用 DROP TABLE 具有 MERGE 表仅下降了 MERGE 规范。 基础表不受影响。

要创建 MERGE 表,必须指定一个 选项,指示 要使用的表。 您可以选择指定一个 选项来控制如何进入 表中。 使用 的值分别 导致在第一个或最后一个基础表中进行插入。 如果您没有指定任何 选项,或者您使用值指定它 ,请插入 UNION=(list-of-tables) MyISAM INSERT_METHOD MERGE FIRST LAST INSERT_METHOD NO MERGE 则不允许 表中 并且尝试这样做会导致错误。

以下示例显示如何创建 MERGE 表:

mysql> CREATE TABLE t1 (
    - >     a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    - >     message CHAR(20)) ENGINE=MyISAM;
mysql> CREATE TABLE t2 (
    - >     a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    - >     message CHAR(20)) ENGINE=MyISAM;
mysql> INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
mysql> INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
mysql> CREATE TABLE total (
    - >     a INT NOT NULL AUTO_INCREMENT,
    - >     message CHAR(20), INDEX(a))
    - >    ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

在基础 表中 a 被索引为a ,但不在 表中。 在那里它被索引但不是 因为 表不能强制基础表集的唯一性。 (类似地, 基础表中 具有 索引 的列 应该在 表中 编制索引, 但不能作为 索引编制索引。) PRIMARY KEY MyISAM MERGE PRIMARY KEY MERGE UNIQUE MERGE UNIQUE

创建 MERGE 表后,您可以使用它来发出对整个表组进行操作的查询:

MySQL的> SELECT * FROM total;
+  -  + --------- +
| a | 消息|
+  -  + --------- +
| 1 | 测试|
| 2 | 表|
| 3 | t1 |
| 1 | 测试|
| 2 | 表|
| 3 | t2 |
+  -  + --------- +

要将 MERGE 重新映射 到不同的 MyISAM 集合 ,可以使用以下方法之一:

  • DROP MERGE 表并重新创建它。

  • 使用 来改变底层表的列表。 ALTER TABLE tbl_name UNION=(...)

    也可以使用 ALTER TABLE ... UNION=() (即 使用 UNION 子句)删除所有基础表。 但是,在这种情况下,表实际上是空的并且插入失败,因为没有基础表来获取新行。 这样的表可能有用作创建新 MERGE 的模板 CREATE TABLE ... LIKE

基础表定义和索引必须与表的定义紧密 MERGE 相符。 MERGE 打开 作为 表的 一部分的 表时,而不是在 MERGE 创建表 时,将 检查一致性 如果任何表未通过一致性检查,则触发打开表的操作将失败。 这意味着更改a中表的定义 MERGE 可能会在 MERGE 访问表 时导致失败 应用于每个表的一致性检查是:

  • 基础表和 MERGE 表必须具有相同的列数。

  • 基础表和 MERGE 表中 的列顺序 必须匹配。

  • 此外, MERGE 还比较 了父 表和基础表中 每个相应列的规范, 并且必须满足以下检查:

    • 基础表和 MERGE 表中 的列类型 必须相等。

    • 基础表和 MERGE 表中 的列长度 必须相等。

    • 基础表和 MERGE 表的列可以是 NULL

  • 基础表必须至少具有与 MERGE 一样多的索引 基础表可能有比 MERGE 更多的索引 ,但不能少。

    注意

    存在一个已知问题,即同一列上的索引在 MERGE 表和基础 MyISAM 表中的 顺序必须相同 请参阅Bug#33653。

    每个索引必须满足以下检查:

    • 基础表和 MERGE 的索引类型 必须相同。

    • 基础表和 MERGE 的索引定义中的索引部分(即复合索引中的多个列)的数量 必须相同。

    • 对于每个索引部分:

      • 索引部分长度必须相等。

      • 索引部件类型必须相等。

      • 索引部分语言必须相同。

      • 检查索引部分是否可以 NULL

如果 MERGE 由于基础表的问题而无法打开或使用表,则 CHECK TABLE 显示有关哪个表导致问题的信息。

其他资源

16.7.1 MERGE表的优点和缺点

MERGE 表可以帮助您解决以下问题:

  • 轻松管理一组日志表。 例如,您可以将来自不同月份的数据放入单独的表中,使用 myisampack 压缩其中一些表, 然后创建一个 MERGE 表以将它们用作一个表。

  • 获得更快的速度。 您可以根据某些条件拆分大型只读表,然后将各个表放在不同的磁盘上。 MERGE 这种方式构造 表可能比使用单个大表快得多。

  • 执行更有效的搜索。 如果您确切地知道要查找的内容,则可以仅搜索其中一个基础表以查找某些查询,并将 MERGE 表格用于其他 查询 您甚至可以使用许多不同的 MERGE 表来使用重叠的表集。

  • 执行更有效的维修。 修复映射到 MERGE 表的 单个较小的 表比修复单个大表 更容易

  • 立即将多个表映射为一个。 MERGE ,因为它使用的各个表的索引表不需要维护它自己的索引。 因此, MERGE 表集合的 创建或重新映射速度 非常 快。 MERGE 即使未 创建索引,您仍必须在创建 时指定索引定义 。)

  • 如果您有一组表,可以根据需要从中创建大表,则可以根据需要从中创建 MERGE 表。 这速度更快,节省了大量磁盘空间。

  • 超过操作系统的文件大小限制。 每个 MyISAM 表都受此限制的约束,但 MyISAM 不是表 的集合

  • 您可以 MyISAM 通过定义 MERGE 映射到该单个表 表来 创建别名或同义词 这样做不会产生明显的性能影响( memcpy() 每次读取 只需要几次间接调用和 调用)。

MERGE 的缺点 是:

  • 您只能 MyISAM MERGE 使用相同 表。

  • 某些 MyISAM 功能在 MERGE 表格 中不可用 例如,您无法 FULLTEXT MERGE 创建 索引 (您可以 FULLTEXT 在基础 MyISAM 创建 索引 ,但不能 MERGE 使用全文搜索来搜索表。)

  • 如果 MERGE 表是非临时表,则所有基础 MyISAM 表必须是非临时表。 如果 MERGE 表是临时的,则 MyISAM 表可以 是临时 表和非临时表。

  • MERGE 表使用的文件描述符多于 MyISAM 表。 如果10个客户端使用 MERGE 映射到10个表的表,则服务器使用(10×10)+ 10个文件描述符。 (10个客户端中的每个客户端有10个数据文件描述符,客户端共享10个索引文件描述符。)

  • 索引读取速度较慢。 当您读取索引时, MERGE 存储引擎需要对所有基础表发出读取以检查哪一个与给定索引值最匹配。 要读取下一个索引值, MERGE 存储引擎需要搜索读取缓冲区以查找下一个值。 只有当一个索引缓冲区用完时,存储引擎才需要读取下一个索引块。 这使得 MERGE 索引 eq_ref 搜索 速度慢得多 ,但搜索 速度 却慢得多 ref 有关详细信息 eq_ref ,并 ref 请参见 第13.8.2,“EXPLAIN语法”

16.7.2 MERGE表问题

以下是 MERGE 表的 已知问题

  • 在5.1.23之前的MySQL Server版本中,可以使用非临时子MyISAM表创建临时合并表。

    从版本5.1.23开始,MERGE子项通过父表被锁定。 如果父母是临时的,那么它没有被锁定,所以孩子们也没有被锁定。 并行使用MyISAM表会破坏它们。

  • 如果您使用 ALTER TABLE MERGE 更改 为另一个存储引擎,则会丢失到基础表的映射。 而是将基础 MyISAM 表中 的行 复制到更改的表中,然后使用指定的存储引擎。

  • INSERT_METHOD 一个表选择 MERGE 表指示哪个底层 MyISAM 使用表插入到 MERGE 表中。 但是,对该 AUTO_INCREMENT 表的表选项的 使用 MyISAM 对于插入表中没有任何影响, MERGE 直到至少一行已直接插入 MyISAM 表中。

  • 一个 MERGE 表不能保持对整个表唯一性约束。 执行时 INSERT ,数据将进入第一个或最后一个 MyISAM 表(由 INSERT_METHOD 选项 确定 )。 MySQL确保唯一键值在该 MyISAM 表中 保持唯一 ,但不 保留 集合中的所有基础表。

  • 由于 MERGE 引擎无法对基础表集强制实施唯一性,因此 REPLACE 无法按预期工作。 两个关键事实是:

    • REPLACE 只能在它要写入的基础表中检测唯一键冲突(由 INSERT_METHOD 选项 确定 )。 这与 MERGE 表格本身的 违规行为不同

    • 如果 REPLACE 检测到唯一的密钥冲突,它将仅更改它写入的基础表中的相应行; 也就是说,由 INSERT_METHOD 选项 确定的第一个或最后一个表

    类似的考虑适用于 INSERT ... ON DUPLICATE KEY UPDATE

  • MERGE 表不支持分区。 也就是说,您不能对 MERGE 表进行 分区 ,也不能对 MERGE 表的 任何 基础 MyISAM 表进行分区。

  • 你不应该使用 ANALYZE TABLE REPAIR TABLE OPTIMIZE TABLE ALTER TABLE DROP TABLE DELETE 没有一个 WHERE 条款,或 TRUNCATE TABLE 任何被映射到一个开放的表的 MERGE 表。 如果这样做, MERGE 表格仍可能引用原始表格并产生意外结果。 要解决此问题,请 MERGE 通过 FLUSH TABLES 在执行任何命名操作之前 发出 语句来 确保没有 表保持打开状态

    意外的结果包括 MERGE 上的操作可能 会报告表损坏。 如果在基础 MyISAM 上的一个命名操作之后发生这种情况 ,则损坏消息是虚假的。 要处理此问题,请 FLUSH TABLES 在修改 MyISAM 发出 语句

  • DROP TABLE 在表中使用的 MERGE 表在Windows上不起作用,因为 MERGE 存储引擎的表映射在MySQL的上层隐藏。 Windows不允许删除打开的文件,因此首先必须刷新所有 MERGE 表(使用 FLUSH TABLES )或删除 MERGE 表,然后再删除表。

  • 访问表时(例如,作为 语句的 一部分),将检查 MyISAM 表和 MERGE 的定义 检查 通过比较列顺序,类型,大小和关联索引来 确保 表的定义 和父 表定义匹配。 如果表之间存在差异,则返回错误并且语句失败。 由于在打开表时会进行这些检查,因此对单个表定义的任何更改(包括列更改,列排序和引擎更改)都将导致语句失败。 SELECT INSERT MERGE

  • MERGE 表中 的索引顺序 及其基础表应该相同。 如果您使用 ALTER TABLE UNIQUE 表中使用的 MERGE 添加 索引 ,然后使用 ALTER TABLE 上添加非唯一索引 MERGE ,则如果基础表中已存在非 唯一索引,则 表的索引顺序不同。 (这是因为 在非唯一索引之前 ALTER TABLE 放置 UNIQUE 索引以便于快速检测重复键。)因此,对具有此类索引的表的查询可能会返回意外结果。

  • 如果遇到类似于 ERROR 1017(HY000) tbl_name 的错误消息 :找不到文件:'。 MRR'(错误号:2) ,它通常表示某些基础表不使用 MyISAM 存储引擎。 确认所有这些表都是 MyISAM

  • 表中的最大行数 MERGE 为2 64 (~1.844E + 19;与 MyISAM 相同 )。 无法将多个 MyISAM 合并 到一个 MERGE 具有超过此行数的表中。

  • 目前已知 MyISAM 使用具有父表的不同行格式 的基础 MERGE 失败。 请参阅Bug#32364。

  • 生效 MERGE 时, 您无法更改非临时 的联合列表 LOCK TABLES 以下就 不能 正常工作:

    CREATE TABLE m1 ... ENGINE = MRG_MYISAM ......;
    LOCK TABLES t1 WRITE,t2 WRITE,m1 WRITE;
    ALTER TABLE m1 ... UNION =(t1,t2)......;
    

    但是,您可以使用临时 MERGE 执行此操作

  • 您既不能创建一个 MERGE CREATE ... SELECT ,也 不能创建 临时 MERGE 表,也 不能创建非 临时 MERGE 表。 例如:

    CREATE TABLE m1 ... ENGINE = MRG_MYISAM ... SELECT ...;

    尝试这样做会导致错误: tbl_name 不是 BASE TABLE

  • 在某些情况下, 如果基础表包含 ,则基础表 PACK_KEYS 中的 不同 表选项值 MERGE 会导致意外结果 作为解决方法,用于 确保所有涉及的表具有相同的 值。 (缺陷号码#50646) CHAR BINARY ALTER TABLE PACK_KEYS

16.8 FEDERATED存储引擎

FEDERATED 存储引擎,您无需使用复制或群集技术访问从远程MySQL数据库的数据。 查询本地 FEDERATED 表会自动从远程(联合)表中提取数据。 没有数据存储在本地表中。

要从 FEDERATED 源代码构建MySQL, 要包含 存储引擎,请 使用该 选项 调用 CMake -DWITH_FEDERATED_STORAGE_ENGINE

FEDERATED 存储引擎默认情况下未在运行的服务器启用; 要启用 FEDERATED ,您必须使用该 --federated 选项 启动MySQL服务器二进制文件

要检查 FEDERATED 引擎 的源代码 ,请查看 storage/federated MySQL源代码分发 目录。

16.8.1联合存储引擎概述

使用其中一个标准存储引擎(例如 MyISAM CSV InnoDB 创建表时 ,该表由表定义和关联数据组成。 创建 FEDERATED 表时,表定义相同,但数据的物理存储在远程服务器上处理。

FEDERATED 表由两个部分组成:

  • 远程服务器 与数据库表,其又由表定义(存储在MySQL数据字典)和相关的表中的。 远程表的表类型可以是远程 mysqld 服务器 支持的任何类型 ,包括 MyISAM InnoDB

  • 本地服务器 与数据库表,其中表定义在远程服务器上匹配相应的表的。 表定义存储在数据字典中。 本地服务器上没有数据文件。 相反,表定义包括指向远程表的连接字符串。

FEDERATED 本地服务器 上的 表上 执行查询和语句时 ,通常会从本地数据文件插入,更新或删除信息的操作将被发送到远程服务器以供执行,在远程服务器上更新数据文件或返回远程服务器的匹配行。

FEDERATED 表格设置 的基本结构 如图16.2“FEDERATED表结构”所示

图16.2联合表结构

内容在周围文本中描述。

当客户端发出引用 FEDERATED 的SQL语句时, 本地服务器(执行SQL语句的位置)与远程服务器(物理存储数据的位置)之间的信息流如下:

  1. 存储引擎查看 FEDERATED 表所具有的 每个列, 并构造引用远程表的相应SQL语句。

  2. 使用MySQL客户端API将语句发送到远程服务器。

  3. 远程服务器处理该语句,本地服务器检索该语句生成的任何结果(受影响的行计数或结果集)。

  4. 如果语句生成结果集,则每列都将转换为 FEDERATED 引擎期望的 内部存储引擎格式, 并可用于将结果显示给发出原始语句的客户端。

本地服务器使用MySQL客户端C API函数与远程服务器通信。 它调用 mysql_real_query() 发送语句。 要读取结果集,它使用 mysql_store_result() 并一次一个地获取行 mysql_fetch_row()

16.8.2如何创建FEDERATED表

要创建 FEDERATED 表,您应该按照以下步骤操作:

  1. 在远程服务器上创建表。 或者,可以使用该 SHOW CREATE TABLE 语句 记下现有表的表定义

  2. 使用相同的表定义在本地服务器上创建表,但添加将本地表链接到远程表的连接信息。

例如,您可以在远程服务器上创建以下表:

CREATE TABLE test_table(
    id INT(20)NOT NULL AUTO_INCREMENT,
    name VARCHAR(32)NOT NULL DEFAULT'',
    其他INT(20)NOT NULL DEFAULT'0',
    PRIMARY KEY(id),
    INDEX名称(名称),
    INDEX other_key(其他)
ENGINE = MyISAM数据
DEFAULT CHARSET = utf8mb4;

要创建将联合到远程表的本地表,有两个选项可用。 您可以创建本地表并指定用于使用连接到远程表的连接字符串(包含服务器名称,登录名,密码) CONNECTION ,也可以使用先前使用该 CREATE SERVER 语句 创建的现有连接

重要

创建本地表时,它 必须 具有与远程表相同的字段定义。

注意

您可以 FEDERATED 通过向主机上的表添加索引来 提高 的性能 发生优化是因为发送到远程服务器的查询将包含该 WHERE 子句 的内容, 并将被发送到远程服务器并随后在本地执行。 这减少了否则将从服务器请求整个表进行本地处理的网络流量。

16.8.2.1使用CONNECTION创建FEDERATED表

要使用第一种方法,必须 CONNECTION CREATE TABLE 语句中 的引擎类型之后 指定 字符串 例如:

CREATE TABLE federated_table(
    id INT(20)NOT NULL AUTO_INCREMENT,
    name VARCHAR(32)NOT NULL DEFAULT'',
    其他INT(20)NOT NULL DEFAULT'0',
    PRIMARY KEY(id),
    INDEX名称(名称),
    INDEX other_key(其他)
ENGINE = FEDERATED
DEFAULT CHARSET = utf8mb4
CONNECTION = '的MySQL:// fed_user @ REMOTE_HOST:9306 /联合/ TEST_TABLE';
注意

CONNECTION 替换 COMMENT 以前版本的MySQL中使用的。

CONNECTION 字符串包含连接到远程服务器所需的信息,该服务器包含将用于物理存储数据的表。 连接字符串指定服务器名称,登录凭据,端口号和数据库/表信息。 在该示例中,远程表位于服务器上 remote_host ,使用端口9306.名称和端口号应与要用作远程表的远程MySQL服务器实例的主机名(或IP地址)和端口号相匹配。

连接字符串的格式如下:

scheme:// user_name[:password] @ host_name[:port_num] db_name//tbl_name

哪里:

  • scheme :公认的连接协议。 此时仅 mysql 支持作为 scheme 值。

  • user_name :连接的用户名。 此用户必须已经在远程服务器上创建,并且必须具有适当的特权来执行所需的操作( SELECT INSERT UPDATE 在远程表,等等)。

  • password :(可选)相应的密码 user_name

  • host_name :远程服务器的主机名或IP地址。

  • port_num :(可选)远程服务器的端口号。 默认值为3306。

  • db_name :持有远程表的数据库的名称。

  • tbl_name :远程表的名称。 本地和远程表的名称不必匹配。

示例连接字符串:

CONNECTION = 'mysql的://用户名:密码@主机名:端口/数据库/表名'
CONNECTION = 'mysql的://用户名@主机名/数据库/表名'
CONNECTION = 'mysql的://用户名:密码@主机名/数据库/表名'

16.8.2.2使用CREATE SERVER创建FEDERATED表

如果要 FEDERATED 在同一服务器上 创建多个 表,或者如果要简化创建 FEDERATED 的过程 ,则可以使用该 CREATE SERVER 语句定义服务器连接参数,就像使用 CONNECTION 字符串一样。

CREATE SERVER 声明 的格式 是:

创建服务器
 server_name
外部数据包装wrapper_name
选项(option[,option] ...)

server_name 创建一个新的时,在连接字符串中使用的 FEDERATED 表。

例如,要创建与 CONNECTION 字符串 相同的服务器连接

CONNECTION = '的MySQL:// fed_user @ REMOTE_HOST:9306 /联合/ TEST_TABLE';

您将使用以下语句:

创建服务器fedlink
FOREIGN DATA WRAPPER mysql
选项(USER'feed_user',HOST'remote_host',PORT 9306,DATABASE'federated');

要创建 FEDERATED 使用此连接 表,仍然使用 CONNECTION 关键字,但指定在 CREATE SERVER 语句中 使用的名称

CREATE TABLE test_table(
    id INT(20)NOT NULL AUTO_INCREMENT,
    name VARCHAR(32)NOT NULL DEFAULT'',
    其他INT(20)NOT NULL DEFAULT'0',
    PRIMARY KEY(id),
    INDEX名称(名称),
    INDEX other_key(其他)
ENGINE = FEDERATED
DEFAULT CHARSET = utf8mb4
CONNECTION = 'FEDLINK / TEST_TABLE';

此示例中的连接名称包含connection( fedlink )的名称和 test_table 要链接 的表( 的名称, 以斜杠分隔。 如果仅指定不带表名的连接名,则使用本地表的表名。

有关更多信息 CREATE SERVER ,请参见 第13.1.18节“CREATE SERVER语法”

CREATE SERVER 语句接受与 CONNECTION 字符串 相同的参数 CREATE SERVER 语句更新 mysql.servers 表中 的行 有关连接字符串中的参数, CREATE SERVER 语句中的 选项 以及表中的列 之间的对应关系的信息,请参阅下 mysql.servers 表。 作为参考, CONNECTION 字符串 的格式 如下:

scheme:// user_name[:password] @ host_name[:port_num] db_name//tbl_name
描述 CONNECTION CREATE SERVER 选项 mysql.servers
连接方案 scheme wrapper_name Wrapper
远程用户 user_name USER Username
远程密码 password PASSWORD Password
远程主机 host_name HOST Host
远程端口 port_num PORT Port
远程数据库 db_name DATABASE Db

16.8.3联合存储引擎注释和提示

使用 FEDERATED 存储引擎 时,您应该注意以下几点

  • FEDERATED 表可以复制到其他从属服务器,但必须确保从服务器能够使用 CONNECTION 字符串(或 mysql.servers 表中 的行)中 定义的用户/密码组合 来连接到远程服务器。

以下各项表示 FEDERATED 存储引擎执行和不支持的功能:

  • 远程服务器必须是MySQL服务器。

  • 在尝试通过 访问表之前 FEDERATED 表指向 的远程表 必须 存在 FEDERATED

  • 一个 FEDERATED 表可以指向另一个表,但是必须注意不要创建循环。

  • FEDERATED 台不支持通常意义上的指标; 因为远程处理对表数据的访问,实际上它是使用索引的远程表。 这意味着,对于无法使用任何索引的查询,因此需要进行全表扫描,服务器将从远程表中提取所有行并在本地过滤它们。 出现这种情况,无论任何 WHERE LIMIT 与该使用 SELECT 说明; 这些子句本地应用于返回的行。

    无法使用索引的查询因此可能导致性能低下和网络过载。 另外,由于返回的行必须存储在内存中,这样的查询也可能导致本地服务器交换,甚至挂起。

  • 创建 FEDERATED 时应小心, 因为 MyISAM 可能不支持 来自等效 表或其他表 的索引定义 例如,在创建一个 FEDERATED 表与索引前缀 VARCHAR TEXT BLOB 列将失败。 以下定义 MyISAM 有效:

    CREATE TABLE`T1`(`A` VARCHAR(100),UNIQUE KEY(`A`(30)))ENGINE = MYISAM;

    此示例中的键前缀与 FEDERATED 引擎 不兼容, 等效语句将失败:

    CREATE TABLE`T1`(`A` VARCHAR(100),UNIQUE KEY(`A`(30)))ENGINE = FEDERATED
      CONNECTION = 'MYSQL://127.0.0.1:3306 / TEST / T1';

    如果可能,在远程服务器和本地服务器上创建表时,应尝试分离列和索引定义,以避免出现这些索引问题。

  • 在内部,实现使用 SELECT INSERT UPDATE ,和 DELETE ,但不会 HANDLER

  • FEDERATED 存储引擎支持 SELECT INSERT UPDATE DELETE TRUNCATE TABLE ,和索引。 它不支持 ALTER TABLE 也不支持 任何直接影响表结构的数据定义语言语句 DROP TABLE 当前实现不使用预准备语句。

  • FEDERATED 接受 INSERT ... ON DUPLICATE KEY UPDATE 语句,但如果发生重复键违规,语句将失败并显示错误。

  • 不支持交易。

  • FEDERATED 执行批量插入处理,以便批量发送多个行到远程表,从而提高性能。 此外,如果远程表是事务性的,则它使远程存储引擎能够在发生错误时正确执行语句回滚。 此功能具有以下限制:

    • 插入的大小不能超过服务器之间的最大数据包大小。 如果插入超过此大小,则会将其分成多个数据包,并且可能会出现回滚问题。

    • 不会发生批量插入处理 INSERT ... ON DUPLICATE KEY UPDATE

  • 有没有办法让 FEDERATED 引擎知道,如果远程表已经改变。 这样做的原因是该表必须像数据文件一样工作,该数据文件永远不会被数据库系统以外的任何东西写入。 如果远程数据库有任何更改,则可能会破坏本地表中数据的完整性。

  • 使用 CONNECTION 字符串时,不能在密码中使用“@”字符。 您可以使用该 CREATE SERVER 语句创建服务器连接 来解决此限制

  • insert_id timestamp 选项都不会传播到数据提供者。

  • DROP TABLE FEDERATED 发出的 任何 语句 只会删除本地表,而不会删除远程表。

  • FEDERATED 表不适用于查询缓存。

  • FEDERATED 不支持用户定义的分区

16.8.4联合存储引擎资源

以下附加资源可用于 FEDERATED 存储引擎:

16.9示例存储引擎

EXAMPLE 存储引擎是一个存根引擎,什么都不做。 其目的是作为MySQL源代码中的一个示例,说明如何开始编写新的存储引擎。 因此,开发人员主要关注它。

要从 EXAMPLE 源代码构建MySQL, 要启用 存储引擎,请 使用该 选项 调用 CMake -DWITH_EXAMPLE_STORAGE_ENGINE

要检查 EXAMPLE 引擎 的源代码 ,请查看 storage/example MySQL源代码分发 目录。

创建 EXAMPLE 表时,不会创建任何文件。 没有数据可以存储到表中。 检索返回空结果。

MySQL的> CREATE TABLE test (i INT) ENGINE = EXAMPLE;
查询OK,0行受影响(0.78秒)

MySQL的> INSERT INTO test VALUES(1),(2),(3);
ERROR 1031(HY000):'test'的表存储引擎没有»
                    有这个选择

MySQL的> SELECT * FROM test;
空集(0.31秒)

EXAMPLE 存储引擎不支持索引。

EXAMPLE 存储引擎不支持分区。

16.10其他存储引擎

其他存储引擎可以从使用自定义存储引擎接口的第三方和社区成员处获得。

MySQL不支持第三方引擎。 有关更多信息,文档,安装指南,错误报告或有关这些引擎的任何帮助或帮助,请直接联系引擎开发人员。

有关开发可与可插入存储引擎体系结构一起使用的客户存储引擎的更多信息,请参阅 MySQL内部:编写自定义存储引擎

16.11 MySQL存储引擎体系结构概述

MySQL可插拔存储引擎架构使数据库专业人员能够针对特定应用需求选择专用存储引擎,同时完全不需要管理任何特定应用编码要求。 MySQL服务器体系结构将应用程序编程人员和DBA与存储级别的所有低级实现细节隔离开来,从而提供一致且简单的应用程序模型和API。 因此,尽管不同存储引擎之间存在不同的功能,但应用程序可以避免这些差异。

可插拔存储引擎架构提供了一组标准的管理和支持服务,这些服务在所有底层存储引擎中都很常见。 存储引擎本身是数据库服务器的组件,它实际上对在物理服务器级别维护的基础数据执行操作。

这种高效的模块化架构为那些希望专门针对特定应用需求的用户提供了巨大的好处 - 例如数据仓库,事务处理或高可用性情况 - 同时享受利用独立于任何一个的一组接口和服务的优势存储引擎。

应用程序员和DBA通过连接器API和存储引擎上方的服务层与MySQL数据库进行交互。 如果应用程序更改带来了需要更改底层存储引擎的要求,或者添加了一个或多个存储引擎以支持新需求,则无需重要的编码或流程更改即可使工作正常进行。 MySQL服务器体系结构通过提供适用于存储引擎的一致且易于使用的API来保护应用程序免受存储引擎的底层复杂性的影响。

16.11.1可插拔存储引擎架构

MySQL Server使用可插拔存储引擎架构,可以将存储引擎加载到正在运行的MySQL服务器中或从中卸载。

插入存储引擎

在使用存储引擎之前,必须使用该 INSTALL PLUGIN 语句 将存储引擎插件共享库加载到MySQL中 例如,如果 EXAMPLE 命名 引擎插件并且命名 example 了共享库 ha_example.so ,则使用以下语句加载它:

INSTALL PLUGIN示例SONAME'ha_example.so';

要安装可插拔存储引擎,插件文件必须位于MySQL插件目录中,发出该 INSTALL PLUGIN 语句 的用户 必须具有 INSERT mysql.plugin 表的 权限

共享库必须位于MySQL服务器插件目录中,其位置由 plugin_dir 系统变量 给出

拔掉存储引擎

要拔出存储引擎,请使用以下 UNINSTALL PLUGIN 语句:

UNINSTALL PLUGIN示例;

如果拔下现有表所需的存储引擎,则这些表将无法访问,但仍将存在于磁盘上(如果适用)。 在拔下存储引擎之前,请确保没有使用存储引擎的表。

16.11.2公共数据库服务器层

MySQL可插拔存储引擎是MySQL数据库服务器中的组件,负责执行数据库的实际数据I / O操作,以及启用和实施针对特定应用程序需求的某些功能集。 使用特定存储引擎的一个主要好处是,您只能获得特定应用程序所需的功能,因此您在数据库中的系统开销更少,最终结果是更高效和更高的数据库性能。 这就是众所周知,MySQL在行业标准基准测试中具有如此高性能,匹配或击败专有单片数据库的原因之一。

从技术角度来看,存储引擎中的一些独特的支持基础架构组件是什么? 一些关键的功能差异包括:

  • 并发 :某些应用程序具有比其他应用程序更精细的锁定要求(例如行级锁定)。 选择正确的锁定策略可以减少开销,从而提高整体性能。 该区域还包括对多版本并发控制或 快照 读取等功能的支持。

  • 事务支持 :并非每个应用程序都需要事务处理,但对于那些需要事务处理的事务,还有非常明确的要求,例如ACID合规性等等。

  • 参照完整性 :需要让服务器通过DDL定义的外键强制实施关系数据库参照完整性。

  • 物理存储 :这涉及表和索引的整体页面大小以及用于将数据存储到物理磁盘的格式。

  • 索引支持 :不同的应用场景往往受益于不同的索引策略。 每个存储引擎通常都有自己的索引方法,尽管有些(例如B树索引)几乎对所有引擎都是通用的。

  • 内存缓存 :不同的应用程序对某些内存缓存策略的响应比其他应用程序更好,因此尽管某些内存缓存对于所有存储引擎(例如用于用户连接的内存)都是通用的,但其他内存缓存仅在特定存储引擎处于运行状态时才会被唯一定义。

  • 性能辅助 :这包括用于并行操作,线程并发,数据库检查点,批量插入处理等的多个I / O线程。

  • 其他目标功能 :这可能包括对地理空间操作的支持,某些数据操作操作的安全限制以及其他类似功能。

每组可插拔存储引擎基础架构组件旨在为特定应用程序提供一组选择性优势。 相反,避免一组组件功能有助于减少不必要的开销。 理所当然地,了解特定应用程序的一组要求并选择合适的MySQL存储引擎会对整体系统效率和性能产生巨大影响。

原文