MySQL 5.5 ограничение внешнего ключа терпит неудачу, когда внешний ключ существует - PullRequest
7 голосов
/ 06 апреля 2011

Только что установил MySQL 5.5 на Mac OS X 10.6 и у меня странная проблема во многих таблицах.Ниже приведен пример.Вставка строки завершается неудачно с ограничением внешнего ключа, когда этого не должно быть.Внешний ключ, на который он ссылается, существует.Любые идеи?

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> 

ОБНОВЛЕНИЕ : После удаления и повторного создания базы данных несколько раз я сделал 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, похоже, работает.Очень удивительно.

Ответы [ 5 ]

8 голосов
/ 07 июня 2011

Похоже, что это ошибка, появившаяся после 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 и воспроизводил ниже:


[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.

1 голос
/ 01 февраля 2013

Не удивительно, ИМХО.Я нашел множество ошибок в MySQL.Например, выполнение запросов с предложениями where, такими как «WHERE some_tinyint_column = 0», не будет производить никаких данных, когда это необходимо, но переписывание предложения как «WHERE (NOT some_tinyint_column = 1)» даст результаты.После некоторых исследований я обнаружил, что это была ошибка, которая должна была быть исправлена, но в используемой версии ошибка все еще была.

Вывод: когда что-то не имеет абсолютно никакого смысла в MySQL, яобычно считается безопасным предполагать, что это ошибка, и начинать поиск информации по этим направлениям.

0 голосов
/ 27 сентября 2013

У меня была такая же ошибка сегодня. В моем случае я использовал сценарий для воссоздания нескольких таблиц со всеми их записями.

Фактически, я понял, что тип «Engine» в моих таблицах был разным: одна была MyISAM, а вторая (ссылка на FK) была InnoDB. Я изменил все свои таблицы на InnoDB, и теперь все работает нормально.

Этот сценарий создаст файл сценария обновления ( Ссылка )

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
0 голосов
/ 07 апреля 2011

* mysql> INSERT INTO Language_Phrases (Language_Id, Label, Phrase) VALUES (1, «exampleLabel», «Some фразу»); ОШИБКА 1452 (23000): Невозможно добавить или обновить дочернюю строку: ... *

Вы пытаетесь вставить 1 как Language_Id, но у таблицы Language есть свойство AUTO_INCREMENT = 3 . В этом случае вы должны использовать 3 или выше.

0 голосов
/ 06 апреля 2011

проверьте атрибуты числового типа Language_Phrases (Language_Id) и Language (Id)

, оба должны быть либо НЕ ПОДПИСАНО ZEROFILL , либо ПОДПИСАН *

...