2011-04-06 118 views
6

剛剛在Mac OS X 10.6上安裝了MySQL 5.5,並且在很多表上有一個奇怪的問題。下面是一個例子。如果不應該插入一行,則會出現外鍵約束失敗。它引用的外鍵確實存在。有任何想法嗎?當外鍵存在時,MySQL 5.5外鍵約束失敗

mysql> show create table Language; 
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                                                                                                                            | 
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Language | CREATE TABLE `Language` (
    `Id` int(11) NOT NULL AUTO_INCREMENT, 
    `Code` varchar(2) NOT NULL, 
    `Name` varchar(63) CHARACTER SET utf8 DEFAULT NULL, 
    `Variant` varchar(63) CHARACTER SET utf8 DEFAULT NULL, 
    `Country_Id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`Id`), 
    UNIQUE KEY `Code` (`Code`,`Country_Id`,`Variant`), 
    KEY `FKA3ACF7789C1796EB` (`Country_Id`), 
    CONSTRAINT `FKA3ACF7789C1796EB` FOREIGN KEY (`Country_Id`) REFERENCES `Country` (`Id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 | 
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> show create table Language_Phrases; 
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table   | Create Table                                                                                     | 
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Language_Phrases | CREATE TABLE `Language_Phrases` (
    `Language_Id` int(11) NOT NULL, 
    `Phrase` varchar(255) DEFAULT NULL, 
    `Label` varchar(255) NOT NULL, 
    PRIMARY KEY (`Language_Id`,`Label`), 
    KEY `FK8B4876F3AEC1DBE9` (`Language_Id`), 
    CONSTRAINT `FK8B4876F3AEC1DBE9` FOREIGN KEY (`Language_Id`) REFERENCES `Language` (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> select * from Language; 
+----+------+----------+---------+------------+ 
| Id | Code | Name  | Variant | Country_Id | 
+----+------+----------+---------+------------+ 
| 1 | en | English |   |  235 | 
| 2 | ro | Romanian |   |  181 | 
+----+------+----------+---------+------------+ 
2 rows in set (0.00 sec) 

mysql> select * from Language_Phrases; 
Empty set (0.00 sec) 

mysql> INSERT INTO Language_Phrases (Language_Id, Label, Phrase) VALUES (1, 'exampleLabel', 'Some phrase'); 
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`dev`.`language_phrases`, CONSTRAINT `FK8B4876F3AEC1DBE9` FOREIGN KEY (`Language_Id`) REFERENCES `Language` (`Id`)) 
mysql> 

UPDATE:刪除和重建數據庫幾次後,我做了show engine innodb status上述失敗的插入操作後,得到了這個令人驚訝的結果。父語言表未找到!這似乎很奇怪...有什麼想法?

------------------------ 
LATEST FOREIGN KEY ERROR 
------------------------ 
110406 9:55:49 Transaction: 
TRANSACTION CA3B, ACTIVE 0 sec, OS thread id 4494462976 inserting 
mysql tables in use 1, locked 1 
1 lock struct(s), heap size 376, 0 row lock(s) 
MySQL thread id 25, query id 50720 localhost root update 
INSERT INTO Language_Phrases (Language_Id, Label, Phrase) VALUES (1, 'exampleLabel', 'Some phrase') 
Foreign key constraint fails for table `dev`.`language_phrases`: 
, 
    CONSTRAINT `FK8B4876F3AEC1DBE9` FOREIGN KEY (`Language_Id`) REFERENCES `Language` (`Id`) 
Trying to add to index `PRIMARY` tuple: 
DATA TUPLE: 5 fields; 
0: len 4; hex 80000001; asc  ;; 
1: len 17; hex 747970654d69736d617463682e79656172; asc exampleLabel;; 
2: len 6; hex 00000000ca3b; asc  ;;; 
3: len 7; hex 00000000000000; asc  ;; 
4: len 21; hex 59656172206d7573742062652061206e756d626572; asc Some phrase;; 

But the parent table `dev`.`Language` 
or its .ibd file does not currently exist! 

更新2:原來,這簡直是在MySQL中的大規模錯誤。顯然最新版本的MySQL在mac os X 10.6下不能正常工作(也許早期版本?)。降級到5.5.8似乎工作。非常令人驚訝。

+1

有沒有到這個錯誤被提到一個鏈接?我有同樣的問題(mysql5.5和osx10.6),並希望閱讀更多。 – 2011-04-13 14:58:46

+0

我沒有方便的鏈接,我們在MySQL論壇中找到了它們,並且還有一個錯誤報告。 – 2011-04-14 17:32:19

+0

有這個完全相同的問題,感謝張貼這個傢伙。這在過去幾天一直令我瘋狂。 – 2011-09-26 15:32:32

回答

8

這確實出現了一個錯誤,因爲MySQL的5.5.9在Mac OS X介紹: http://bugs.mysql.com/bug.php?id=60309

它被標記爲固定在5.5.13(月發行31),並在發行說明中提到: http://dev.mysql.com/doc/refman/5.5/en/news-5-5-13.html

另外,還有在我已經驗證了5.5.10及以下轉載的bug報告中列出的解決方法:

 

[20 Mar 11:29] Harald Neiss 

I also received a new MBP and reinstalled MySQL (mysql-5.5.10-osx10.6-x86_64). Finally I 
came across the same problem as described above. So here is the query result and what I 
did to solve it. 

mysql> show variables like 'lower%'; 
+------------------------+-------+ 
| Variable_name   | Value | 
+------------------------+-------+ 
| lower_case_file_system | ON | 
| lower_case_table_names | 2  | 
+------------------------+-------+ 
2 rows in set (0.00 sec) 

Dropped database, created the file /etc/my.cnf with the following content: 

[mysqld] 
lower_case_table_names=1 

Restarted the MySQL daemon and repeated the query: 

mysql> show variables like 'lower%'; 
+------------------------+-------+ 
| Variable_name   | Value | 
+------------------------+-------+ 
| lower_case_file_system | ON | 
| lower_case_table_names | 1  | 
+------------------------+-------+ 
2 rows in set (0.00 sec) 

I recreated the tables and everything works fine. 

+0

謝謝!我會檢查出最新版本的mysql! – 2011-06-07 07:44:09

+0

升級到OS X Lion後,再次出現此問題。上面提到的解決方法這次似乎並不奏效,所以我不得不升級MySQL。通過[homebrew](https://github.com/mxcl/homebrew)安裝的版本5.5.14可以滿足您的需求! – penfold 2011-08-15 01:23:50

0

檢查Language_Phrases (Language_Id)LanguageId)的數字類型屬性

both should be either UNSIGNED ZEROFILL or SIGNED

+0

如何檢查或設置它們是否已簽名或未簽名? – 2011-04-06 13:53:36

+0

他們都是'int(11)'根據'describe' – 2011-04-06 13:54:08

+0

轉到'phpmyadmin'並檢查兩者..可能是屬性名稱中的一些空間? – diEcho 2011-04-07 04:27:26

0

*的MySQL> INSERT INTO Language_Phrases(LANGUAGE_ID,標籤,詞組)VALUES(1, 'exampleLabel', '部分短語'); ERROR 1452(23000):不能添加或更新子行:... *

您正在試圖插入爲LANGUAGE_ID,但表語言具有財產AUTO_INCREMENT = 。在這種情況下,你應該使用3或更高。

+0

我給出了語言的輸出,其中包括2行(這就是auto_increment = 3的原因) – 2011-04-07 14:30:53

+0

嘗試重新創建FK;有同樣的錯誤 - http://forums.mysql.com/read.php?135407929,407929#msg-407929 – Devart 2011-04-08 06:56:07

+0

刪除並重新創建外鍵不會修復錯誤。但有趣的線程。看起來MySQL的最後3個版本都很糟糕,至少在Mac OS X 10.6上。降級到MySQL 5.5.8爲我們工作,以及該線程... – 2011-04-09 04:14:51

1

並不奇怪恕我直言。我在MySQL中發現了很多錯誤。例如,使用Where子句(如WHERE some_tinyint_column = 0)運行查詢將不會產生任何數據,但將該子句重寫爲「WHERE(NOT some_tinyint_column = 1)」會產生結果。經過一番研究,我發現這是一個本來應該修復的bug,但是在我使用的版本中,bug仍然存在。結論:在MySQL中絕對沒有意義的事情時,我通常認爲它是安全的,可以假設它是一個bug,並開始研究這些信息。

0

今天我有同樣的錯誤。就我而言,我已經使用腳本重新創建了一些包含所有記錄的表格。事實上,我已經意識到我的表格之間的「引擎」類型是不同的:一個是MyISAM,第二個(FK的引用)是InnoDB。我已將所有表格更改爲InnoDB,現在一切正常。

這個腳本會產生一個更新腳本文件(Reference

mysql -u DB_USER -pDB_PASSWORD --default-character-set=utf8 DATABASE_NAME -e "SELECT CONCAT('ALTER TABLE ', table_name, ' ENGINE=InnoDB;') AS sql_statements FROM information_schema.tables AS tb WHERE table_schema = database() AND ENGINE = 'MyISAM' AND TABLE_TYPE = 'BASE TABLE' ORDER BY table_name DESC;" > ./alter_InnoDb.sql 

您必須刪除的第一行「alter_InnoDb.sql」,包含文本「sql_statements」行。

之後,您可以在數據庫中執行腳本來更正此錯誤:

mysql -u DB_USER -pDB_PASSWORD --default-character-set=utf8 DATABASE_NAME < ./ alter_InnoDb.sql