(错误?)InnoDB MySQL 错误1025,errno 150 外键

3

我有一张表,想要更改主键。以下是该表的定义。

CREATE TABLE `tbl_customer` (
  `PersonId` int(11) NOT NULL,
  `Id` int(10) unsigned NOT NULL,
  `Name` varchar(100) collate utf8_spanish_ci NOT NULL,
  `Alias` varchar(50) collate utf8_spanish_ci NOT NULL,
  `Phone` varchar(30) collate utf8_spanish_ci default NULL,
  `Phone2` varchar(30) collate utf8_spanish_ci default NULL,
  `Email` varchar(50) collate utf8_spanish_ci default NULL,
  `Email2` varchar(50) collate utf8_spanish_ci default NULL,
  `RFC` varchar(13) collate utf8_spanish_ci default NULL,
  `AddressStreetName` varchar(45) collate utf8_spanish_ci default NULL,
  `AddressStreetNumber` varchar(45) collate utf8_spanish_ci default NULL,
  `AddressCityWard` varchar(45) collate utf8_spanish_ci default NULL,
  `AddressCityName` varchar(45) collate utf8_spanish_ci default NULL,
  `AddressStateName` varchar(45) collate utf8_spanish_ci default NULL,
  `AddressCountryName` varchar(45) collate utf8_spanish_ci default NULL,
  `AddressPostalCode` int(10) default NULL,
  `IsDistributor` tinyint(1) NOT NULL default '0' COMMENT '1 = Is Distributor, 0 = Is Not Distributor',
  `ParentCustomerId` int(10) NOT NULL default '11' COMMENT 'Our Id is 11, so by default, all customers right now are our children.',
  PRIMARY KEY  (`Id`),
  KEY `fk_tbl_cliente_tbl_cliente1_idx` (`ParentCustomerId`),
  KEY `fk_tbl_cliente_tbl_person1_idx` (`PersonId`),
  KEY `PersonId` (`PersonId`),
  KEY `PersonId_2` (`PersonId`),
  CONSTRAINT `fk_tbl_cliente_tbl_cliente1` FOREIGN KEY (`ParentCustomerId`) REFERENCES `tbl_customer` (`PersonId`),
  CONSTRAINT `fk_tbl_cliente_tbl_person1` FOREIGN KEY (`PersonId`) REFERENCES `zapata`.`tbl_person` (`Id`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci COMMENT='''Customer'' refers to a person or entity to which we provide '$$

现在,当我第一次尝试时:

ALTER TABLE `tbl_customer` DROP PRIMARY KEY;

我的主键是Id。当我试图删除它时,出现了以下问题:


Error Code: 1025. Error on rename of './services/#sql-29a_218cc7f' to './services/tbl_customer' (errno: 150)

因此,我删除了所有引用该表和列的 FOREIGN KEY 约束,但仍然收到相同的错误。我还查看了 SHOW ENGINE INNODB STATUS 并发现以下内容:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
130226 14:41:11 Error in foreign key constraint of table services/tbl_employee_shift:
there is no index in referenced table which would contain
the columns as the first columns, or the data types in the
referenced table do not match to the ones in table. Constraint:
,
  CONSTRAINT fk_tbl_employee_shift_tbl_customer1 FOREIGN KEY (CustomerId) REFERENCES services.tbl_customer (Id) ON UPDATE CASCADE

然而,表services.tbl_employee_shift不存在(虽然曾经存在过,但在我尝试进行更改的几周前已被删除)。因此,我继续进行了...

CREATE TABLE services.tbl_employee_shift(
    CustomerId INT (11)
);
ALTER TABLE services.tbl_employee_shift ADD CONSTRAINT fk_tbl_employee_shift_tbl_customer1 FOREIGN KEY (CustomerId) REFERENCES avatar.tbl_cliente (Id);
ALTER TABLE services.tbl_employee_shift DROP FOREIGN KEY fk_tbl_employee_shift_tbl_customer1;

它可以工作...但是它不能更正必要的信息,似乎InnoDB仍然认为约束 fk_tbl_employee_shift_tbl_customer1 是存在的,因此,“防止删除主键以保持一致性”...

我正在使用MySQL 5.0.95。

编辑:这个问题没有解决,只能绕过去了。

当我们将数据库迁移到一个更新的服务器(相同的mysql版本)时,这个问题才得以纠正,似乎存在一个损坏/幽灵引用到幽灵外键(fk_tbl_employee_shift_tbl_customer1),它阻止了列被删除。由于这个损坏/幽灵fk在新服务器中不存在,所以我可以毫无问题地删除该列。我的猜测是这是一个bug,但不幸的是我无法再现它。


tbl_employee_shift表是在删除tbl_customer的主键之前还是之后被删除的? - berty
在尝试更改tbl_customer的主键之前,tbl_employee_shift已经在几周前被删除了。 - Snivs
tbl_person使用innnoDB存储引擎创建。如果您认为有误,请查看我的SQL语句。据我所知,它是正确的。这似乎是完全意外的行为,因为由于参照外键,PK无法被删除,但是引用先前已被删除。即使如此,可以重新创建并删除相同的外键。完成此操作后,参照仍然会防止删除主键... - Snivs
有最新进展吗?我遇到了相同的问题,但我无法使用外键重建表。每当我尝试时都会出现121错误!难以置信。 - sudol
@sudol 很抱歉耽搁了,实际上这个问题一直没有解决,只有在我们迁移到新服务器时才能进行修正。似乎存在一个损坏的外键引用(fk_tbl_employee_shift_tbl_customer1),导致该列无法删除。由于新服务器中不存在这个“幽灵”外键,所以我可以毫无问题地删除该列。 - Snivs
@Snivs 感谢您的回复。很遗憾,我也找不到一个好的答案。我通过执行mysqldump,然后立即将其加载回来来解决了这个问题。 - sudol
4个回答

3

听起来好像在 foreign_key_checks 设置为 0 的情况下删除了 tbl_employee_shift

foreign_key_checks 设置为 0 还会影响数据定义语句:DROP SCHEMA 即使它包含由模式外的表引用的外键,也会删除一个模式,而 DROP TABLE 会删除具有被其他表引用的外键的表。

由于这种行为已经被记录在文档中,因此必须认为这是按设计进行的,因此不是错误。


有道理!但即使如此,为什么在 foreign_key_checks 设置为 1 的情况下,它允许我重新创建和删除表和外键?编辑:而且,当我删除重新创建的 fk 时,InnoDB 仍然认为引用存在。 - Snivs

1
当外键格式不正确时会出现错误。 SQL 语句是正确的,我在本地主机上运行脚本时也遇到了相同的错误。 解决方法是验证 tbl_person 表是否使用 "InnoDB" 引擎创建。
问候。

tbl_person使用innnoDB存储引擎创建。如果您认为我的SQL不正确,请进行审核。据我所知,它是正确的。这似乎是完全意外的行为,因为由于FK引用它,PK无法被删除,但是引用先前已被删除。即使如此,相同的FK也可以重新创建和删除。在完成此操作后,引用仍然会防止PK被删除... - Snivs
1
我遇到了相同的错误,但我解决了由MyISAM创建的tbl_person表。我的表和你的表之间的区别在于tbl_person表与tbl_customer表位于同一数据库中。我希望这能帮助你。对我的英语表示抱歉。 - chenio
谢谢,Chenio,但这些表非常动态,不能更改为Myisam,我想我必须计划如何在计划维护期间重新创建整个数据库,也许这样我还可以重新创建InnoDB内部目录...没有那个僵尸FK。 - Snivs

0

今天刚遇到这个问题。在任何模式信息表中都没有发现两个受影响的表的迹象。我搜索了各种系统数据库寻找外键,但都无济于事。最后,删除数据库立即解决了问题。


-1

我曾经遇到过类似的错误,MySQL 要求你必须同时拥有键和外键,并且类型和大小要匹配。例如,person.id int(10) 必须映射到 service_customer.person_id int(10),如果类型和大小不一致,MySQL 就会报错。


无关的是,外键已被删除,但仍被视为存在...而且这不是MySQL,而是InnoDB存储引擎。 - Snivs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接