15.7.2 MERGEtable 问题

以下是MERGE个 table 的已知问题:

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

从 5.1.23 版开始,MERGE 子级通过父 table 被锁定。如果 parent 是临时的,则它不会被锁定,因此孩子也不会被锁定。 MyISAMtable 的并行使用损坏了它们。

  • 如果使用ALTER TABLEMERGEtable 更改为另一个存储引擎,则到基础 table 的 Map 将丢失。而是将基础MyISAMtable 中的行复制到更改后的 table 中,然后使用指定的存储引擎。

  • MERGEtable 的INSERT_METHODtable 选项指示要用于插入MERGEtable 的基础MyISAMtable。但是,对该MyISAMtable 使用AUTO_INCREMENT table 选项对插入MERGEtable 无效,直到至少有一行直接插入MyISAMtable 中。

  • MERGEtable 无法维护整个 table 的唯一性约束。当您执行INSERT时,数据将进入第一个或最后一个MyISAMtable(由INSERT_METHOD选项确定)。 MySQL 确保唯一的键值在该MyISAMtable 中保持唯一,但在集合的所有基础 table 中均不唯一。

  • 因为MERGE引擎无法对基础 table 集强制执行唯一性,所以REPLACE不能按预期工作。两个关键事实是:

  • REPLACE只能在要写入的基础 table 中检测到唯一键冲突(由INSERT_METHOD选项确定)。这与MERGEtable 本身中的冲突不同。

    • 如果REPLACE检测到唯一键冲突,它将仅更改要写入的基础 table 中的相应行;即由INSERT_METHOD选项确定的第一个或最后一个 table。

类似的考虑适用于插入...在重复的密钥更新上

  • MERGEtable 不支持分区。也就是说,您不能对MERGEtable 进行分区,也不能对MERGEtable 的基础MyISAMtable 进行分区。

  • 如果没有WHERE子句或TRUNCATE TABLEMap 到打开的MERGEtable 中的任何 table,则不应使用ANALYZE TABLEREPAIR TABLEOPTIMIZE TABLEALTER TABLEDROP TABLEDELETE。如果这样做,MERGEtable 仍可能引用原始 table 并产生意外结果。要变通解决此问题,通过执行任何命名的操作之前发出FLUSH TABLES语句,确保没有MERGEtable 保持打开状态。

意外的结果包括对MERGEtable 的操作将报告 table 损坏的可能性。如果在基础MyISAMtable 上的命名操作之一之后发生这种情况,则损坏消息是虚 Pseudo。要解决此问题,请在修改MyISAMtable 后发出FLUSH TABLES语句。

  • MERGEtable 正在使用的 table 上的DROP TABLE在 Windows 上不起作用,因为MERGE存储引擎的 tableMap 是从 MySQL 的上层隐藏的。 Windows 不允许删除打开的文件,因此在删除 table 之前,首先必须刷新所有MERGEtable(使用FLUSH TABLES)或删除MERGEtable。

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

  • MERGEtable 及其基础 table 中的索引 Sequences 应相同。如果使用ALTER TABLEMERGEtable 中使用的 table 添加UNIQUE索引,然后使用ALTER TABLEMERGEtable 上添加非唯一索引,则如果基础 table 中已经存在非唯一索引,则 table 的索引 Sequences 会有所不同 table。 (发生这种情况是因为ALTER TABLEUNIQUE索引放在非唯一索引之前,以便于快速检测重复键。)因此,对具有此类索引的 table 的查询可能会返回意外结果。

  • 如果遇到类似于错误 1017(HY000)的错误消息:找不到文件:'* tbl_name * .MRG'(错误号:2),则通常 table 明某些基础 table 未使用MyISAM存储引擎。确认所有这些 table 均为MyISAM

  • MERGEtable 中的最大行数为 264(~1.844E 19;与MyISAMtable 相同)。不能将多个MyISAMtable 合并到一个单独的MERGEtable 中,该 table 的行数超过此数目。

  • 当前已知将不同行格式的基础MyISAMtable 与父MERGEtable 一起使用失败。请参阅错误#32364.

  • LOCK TABLES有效时,您无法更改非临时MERGEtable 的联合列 table。以下内容不起作用

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

但是,您可以使用临时的MERGEtable 来执行此操作。

  • 您不能使用CREATE ... SELECT创建MERGEtable,既不能作为临时MERGEtable 也不能将其作为非临时MERGEtable。例如:
CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...;

尝试执行此操作将导致错误:* tbl_name *不是BASE TABLE

  • 在某些情况下,如果基础 table 包含CHARBINARY列,则MERGE和基础 table 中不同的PACK_KEYStable 选项值会导致意外结果。解决方法是,使用ALTER TABLE来确保所有涉及的 table 都具有相同的PACK_KEYS值。错误 35646)