18.7.2 MERGE 表问题
以下是MERGE
表的已知问题:
-
在MySQL Server版本之前的5.1.23,可能创建临时合并表具有非临时子MyISAM表。
从版本5.1.23开始,MERGE子表被锁定通过父表。如果父表是临时的,它不会被锁定,因此子表也不会被锁定。并发使用MyISAM表会损坏它们。
-
如果使用
ALTER TABLE
将MERGE
表更改为另一种存储引擎,映射到 underlying 表的信息将被丢失。相反,来自underlying MyISAM 表的行将被复制到已更改的表中,该表然后使用指定的存储引擎。 -
MERGE
表的INSERT_ METHOD
选项指示哪个underlying MyISAM 表用于将数据插入到MERGE
表中。然而,对于该MyISAM 表使用AUTO_INCREMENT
选项对插入到MERGE
表中的行没有影响,直到至少有一行直接插入到MyISAM 表中。 -
MERGE 表不能维护整个表的唯一约束。当您执行
INSERT
时,数据将被写入到第一个或最后一个MyISAM 表(根据INSERT_ METHOD
选项)。MySQL 确保在该MyISAM 表中唯一键值保持唯一,但不跨越整个表的所有 underlying 表。 -
由于 MERGE 引擎不能对 underlying 表集强制执行唯一约束,
REPLACE
无法按预期工作。两个关键事实是:类似的考虑也适用于
INSERT ... ON DUPLICATE KEY UPDATE
。 -
MERGE
表不支持分区。也就是说,你不能对一个MERGE
表进行分区,也不能对该表的 underlyingMyISAM
表进行分区。 -
你 shouldn't 使用
ANALYZE TABLE
、REPAIR TABLE
、OPTIMIZE TABLE
、ALTER TABLE
、DROP TABLE
、DELETE
without aWHERE
clause,或者TRUNCATE TABLE
在任何映射到一个打开的MERGE
表中的表上。 如果你这样做,MERGE
表可能仍然引用原始表并产生意外结果。要解决这个问题,请在执行任何命名操作之前确保没有打开的MERGE
表存在,可以通过发出FLUSH TABLES
语句来实现。出现的意外结果可能是对MERGE表的操作报告表 Corruption。如果在MyISAM表下层的一些命名操作后发生这种情况,Corruption信息是虚假的。要解决这个问题,可以在修改MyISAM表后执行一个FLUSH TABLES语句。
-
DROP TABLE对一个由MERGE表使用的表无效,因为MERGE存储引擎的表映射被隐藏在 MySQL 的上层。Windows 不允许打开文件被删除,因此您首先必须刷新所有MERGE表(使用FLUSH TABLES)或删除MERGE表,然后才能删除该表。
-
当访问表时(例如,在
SELECT
或INSERT
语句中),MyISAM 表和 MERGE 表的定义将被检查。检查确保表的定义和父 MERGE 表的定义相符,通过比较列顺序、类型、大小和关联索引。如果表之间存在差异,将返回错误语句失败。由于这些检查在打开表时发生,对于单个表的更改,包括列更改、列顺序更改和引擎更改都会导致语句失败。 -
MERGE 表及其 underlying 表中的索引顺序应该相同。如果使用
ALTER TABLE
将 UNIQUE 索引添加到 MERGE 表中,然后使用ALTER TABLE
将非唯一索引添加到 MERGE 表中,但是在 underlying 表中已经存在非唯一索引时,索引顺序不同(因为ALTER TABLE
将 UNIQUE 索引置于非唯一索引前,以便快速检测重复键)。因此,对于具有这样的索引的表,查询可能返回意外结果。 -
如果您遇到类似于ERROR 1017 (HY000): Can't find file: '
tbl_名
.MRG' (errno: 2)的错误消息,这通常表明一些 underlying 表不使用MyISAM
存储引擎。请确认这些表都使用MyISAM
。 -
一个
MERGE
表的最大行数是264(~1.844E+19;与MyISAM
表相同)。不能将多个MyISAM
表合并到一个MERGE
表中,该表将有更多的行。 -
当前使用不同行格式的 underlying
MyISAM
表作为父MERGE
表的子表是已知的失败。请参阅 Bug #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_名
不是BASE TABLE
。 -
在某些情况下,
MERGE
表和 underlying 表之间的PACK_KEYS
表选项值不同,如果underlying 表包含CHAR
或BINARY
列可能会出现意外结果。作为解决方案,可以使用ALTER TABLE
确保所有相关表都具有相同的PACK_KEYS
值。 (Bug #50646)