以下是关于 MERGE
表的已知问题
在 5.1.23 之前的 MySQL Server 版本中,可以使用非临时子 MyISAM 表创建临时合并表。
从版本 5.1.23 开始,MERGE 子表通过父表进行锁定。如果父表是临时的,则不会锁定,因此子表也不会锁定。并行使用 MyISAM 表会导致它们损坏。
如果使用
ALTER TABLE
将MERGE
表更改为其他存储引擎,则对基础表的映射将丢失。相反,基础MyISAM
表中的行将被复制到已更改的表中,该表将使用指定的存储引擎。用于
MERGE
表的INSERT_METHOD
表选项指示对MERGE
表进行插入时要使用哪个基础MyISAM
表。但是,直到至少有一行直接插入到MyISAM
表中,该MyISAM
表的AUTO_INCREMENT
表选项对MERGE
表的插入才有效。MERGE
表无法维护整个表的唯一性约束。执行INSERT
时,数据将进入第一个或最后一个MyISAM
表(由INSERT_METHOD
选项确定)。MySQL 确保唯一键值在该MyISAM
表中保持唯一,但不会在集合中的所有基础表中保持唯一。由于
MERGE
引擎无法对基础表集合强制执行唯一性,因此REPLACE
的效果不符合预期。这两个关键事实是类似的注意事项适用于
INSERT ... ON DUPLICATE KEY UPDATE
。MERGE
表不支持分区。也就是说,您不能对MERGE
表进行分区,MERGE
表的任何基础MyISAM
表也不能进行分区。您不应该在任何映射到打开的
MERGE
表中的表上使用ANALYZE TABLE
、REPAIR TABLE
、OPTIMIZE TABLE
、ALTER TABLE
、DROP TABLE
、DELETE
(不带WHERE
子句)或TRUNCATE TABLE
。如果这样做,MERGE
表可能仍然引用原始表并产生意外结果。为了解决此问题,请在执行任何上述操作之前,确保没有MERGE
表处于打开状态,方法是发出FLUSH TABLES
语句。意外结果包括
MERGE
表上的操作可能会报告表损坏。如果在对基础MyISAM
表执行上述操作之一后发生这种情况,则损坏消息是虚假的。为了处理这种情况,请在修改MyISAM
表后发出FLUSH TABLES
语句。在 Windows 上,对
MERGE
表使用的表执行DROP TABLE
无法正常工作,因为MERGE
存储引擎的表映射对 MySQL 的上层隐藏。Windows 不允许删除打开的文件,因此您必须首先刷新所有MERGE
表(使用FLUSH TABLES
)或在删除表之前删除MERGE
表。在访问表(例如,作为
SELECT
或INSERT
语句的一部分)时,会检查MyISAM
表和MERGE
表的定义。这些检查通过比较列顺序、类型、大小和相关索引来确保表定义和父MERGE
表定义匹配。如果表之间存在差异,则会返回错误并且语句失败。由于这些检查在打开表时进行,因此对单个表的定义进行任何更改(包括列更改、列排序和引擎更改)都会导致语句失败。MERGE
表及其基础表中索引的顺序应该相同。如果使用ALTER TABLE
在MERGE
表中使用的表中添加UNIQUE
索引,然后使用ALTER TABLE
在MERGE
表上添加非唯一索引,如果基础表中已存在非唯一索引,则表的索引排序将不同。(这是因为ALTER TABLE
将UNIQUE
索引放在非唯一索引之前,以便快速检测重复键。)因此,对具有此类索引的表执行查询可能会返回意外结果。如果您遇到类似于 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
。在某些情况下,如果底层表包含
CHAR
或BINARY
列,MERGE
表和底层表之间不同的PACK_KEYS
表选项值会导致意外结果。 作为解决方法,请使用ALTER TABLE
确保所有相关表都具有相同的PACK_KEYS
值。(错误 #50646)