相关文档 下载本手册

MySQL 9.0 参考手册  /  ...  /  MERGE 表问题

18.7.2 MERGE 表问题

以下是关于 MERGE 表的已知问题

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

    从版本 5.1.23 开始,MERGE 子表通过父表进行锁定。如果父表是临时的,则不会锁定,因此子表也不会锁定。并行使用 MyISAM 表会导致它们损坏。

  • 如果使用 ALTER TABLEMERGE 表更改为其他存储引擎,则对基础表的映射将丢失。相反,基础 MyISAM 表中的行将被复制到已更改的表中,该表将使用指定的存储引擎。

  • 用于 MERGE 表的 INSERT_METHOD 表选项指示对 MERGE 表进行插入时要使用哪个基础 MyISAM 表。但是,直到至少有一行直接插入到 MyISAM 表中,该 MyISAM 表的 AUTO_INCREMENT 表选项对 MERGE 表的插入才有效。

  • 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 表也不能进行分区。

  • 您不应该在任何映射到打开的 MERGE 表中的表上使用 ANALYZE TABLEREPAIR TABLEOPTIMIZE TABLEALTER TABLEDROP TABLEDELETE(不带 WHERE 子句)或 TRUNCATE TABLE。如果这样做,MERGE 表可能仍然引用原始表并产生意外结果。为了解决此问题,请在执行任何上述操作之前,确保没有 MERGE 表处于打开状态,方法是发出 FLUSH TABLES 语句。

    意外结果包括 MERGE 表上的操作可能会报告表损坏。如果在对基础 MyISAM 表执行上述操作之一后发生这种情况,则损坏消息是虚假的。为了处理这种情况,请在修改 MyISAM 表后发出 FLUSH TABLES 语句。

  • 在 Windows 上,对 MERGE 表使用的表执行 DROP TABLE 无法正常工作,因为 MERGE 存储引擎的表映射对 MySQL 的上层隐藏。Windows 不允许删除打开的文件,因此您必须首先刷新所有 MERGE 表(使用 FLUSH TABLES)或在删除表之前删除 MERGE 表。

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

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

  • 如果您遇到类似于 ERROR 1017 (HY000): Can't find file: 'tbl_name.MRG' (errno: 2) 的错误消息,通常表示一些基础表没有使用 MyISAM 存储引擎。确认所有这些表都是 MyISAM

  • MERGE 表中的最大行数为 264(约 1.844E+19;与 MyISAM 表相同)。无法将多个 MyISAM 表合并到一个行数超过此数量的单个 MERGE 表中。

  • 目前已知,使用具有不同行格式的基础 MyISAM 表与父 MERGE 表一起使用会导致失败。请参见错误 #32364。

  • LOCK TABLES 生效时,您无法更改非临时 MERGE 表的联合列表。以下操作 起作用

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

    但是,您可以对临时 MERGE 表执行此操作。

  • 您无法使用 CREATE ... SELECT 创建 MERGE 表,无论是作为临时 MERGE 表,还是作为非临时 MERGE 表。例如

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

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

  • 在某些情况下,如果底层表包含 CHARBINARY 列,MERGE 表和底层表之间不同的 PACK_KEYS 表选项值会导致意外结果。 作为解决方法,请使用 ALTER TABLE 确保所有相关表都具有相同的 PACK_KEYS 值。(错误 #50646)