Korzystam z tych kroków, aby utworzyć tabelę my_user
, która już istniała, ale jakoś zniknęła z mojej bazy danych my_db
:
mysql> USE my_db;
mysql> DROP TABLE my_user;
mysql> ERROR 1051 (42S02): Unknown table 'my_user'
mysql> CREATE TABLE my_user (id INT AUTO_INCREMENT NOT NULL, username VARCHAR(255), group_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
mysql> ERROR 1005 (HY000): Can't create table 'my_db.my_user' (errno: -1)
Próbowałem # mysqladmin flush-tables
i powtórzyłem powyższe kroki, ale nie było to pomocne. Zrestartowałem także mysql
usługę, ale nic dobrego.
Jakieś pomysły? Jak dotąd zawiodło mnie Google. Dzięki.
Informacje dodatkowe:
mysql> SHOW engine innodb STATUS;
------------------------
LATEST FOREIGN KEY ERROR
------------------------
140703 15:15:09 Error in foreign key constraint of table my_db/my_user
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
CONSTRAINT "FK_CFBD431E285FAC6D" FOREIGN KEY ("group_id") REFERENCES "my_group" ("id")
my_user
ale błąd dotyczymy_db.user
...CREATE TABLE
kod jest generowany przez bibliotekę Doctrine ORM (PHP).Odpowiedzi:
Architektura InnoDB
ANALIZA
my_user.frm
imy_user.ibd
. Słownik danych nadal ma wpis dla tej tabeli.DROP TABLE my_user;
ponieważ mysqld szukamy_user.frm
pierwszego. Ponieważ niemy_user.frm
, nie można upuścić tabeli.my_user.frm
nie istnieje, nie można go uruchomić,CREATE TABLE my_user ...
ponieważ mysqld uważa, że można utworzyć tabelę, ale następnie odkłada silnik pamięci masowej. InnoDB mówi „Mam już zarejestrowany tablepace_id mojego_użytkownika”.Tę sekwencję zdarzeń można udowodnić, jeśli utworzysz tabelę za pomocą MyISAM. mysqld pozwoli na to. Po przejściu na InnoDB wraca on do słownika danych, który jest wadliwy dla tego jednego wpisu.
Mam dwie sugestie
SUGESTIA # 1
Nie twórz już tabeli o tej nazwie. Użyj innej nazwy tabeli
Spowoduje to zmianę nazwy tabeli w kodzie aplikacji
SUGESTIA # 2
Rozwiązałem ten problem wcześniej w moim poście Tabela InnoDB SELECT zwraca BŁĄD 2006 (HY000): Serwer MySQL zniknął (po awarii zasilania)
źródło
ib_logfile0
iib_logfile1
(wraz zibdata1
). Po imporcie mogłem utworzyćmy_user
tabelę bez żadnych problemów. Dziękuję Rolando!DROP TABLE
. Dzieje się coś złego.Wystarczy dodać moje rozwiązanie, ponieważ miałem podobny problem.
TL; DR
Szczegół
Natrafiłem na nieprzyjemną sytuację, w której instrukcja ALTER TABLE nie powiodła się z powodu wcześniejszego usunięcia klucza obcego. Doprowadziło to do pewnych niespójności w słowniku danych InnoDB (prawdopodobnie z powodu http://bugs.mysql.com/bug.php?id=58215 ).
Powiązane pytanie tutaj: /programming/16857451/error-in-foreign-key-constraint-on-a-droped-table
Błąd przy zmianie nazwy „./db/#sql-482c_8448f” na „./db/visits” (errno: 150)
Ponieważ nie mogłem odzyskać tabeli # sql-482c_8448f do odwiedzin, postanowiłem zaimportować ją z kopii zapasowej wykonanej tuż przed zmianą. Jednak to się nie udało. W trakcie dochodzenia:
SQL / błędy
Próba odtworzenia tabeli bez klucza obcego spowodowała błąd 150
Próba utworzenia go spowodowała błąd 121
W końcu użyłem nowej nazwy klucza obcego. Nie spodziewałem się, że to zadziała, ale pozwoliło to na utworzenie tabeli.
Po prostu upuszczenie tabeli po tym usunęło błędny rekord w INFORMACJE_SCHEMA.INNODB_SYS_FOREIGN, umożliwiając import z oryginalną nazwą klucza obcego.
źródło
Istnieje jeden prosty sposób na obejście tego, choć trzeba przyznać, że w pewnych okolicznościach możesz tego nie chcieć. Ponieważ ten problem wynika z wewnętrznego odwołania InnoDB, możesz po prostu utworzyć tę tabelę o tej samej nazwie i tych samych kolumnach, używając tylko innego silnika pamięci. Natknąłem się na to na slave MySQL i mimo że mistrzem, z którego replikowałem, był InnoDB, odtworzyłem tę jedną tabelę za pomocą MyISAM i mogłem ponownie uruchomić. Specjalnie wybrałem InnoDB dla mojego silnika pamięci masowej w systemie głównym, a na niektórych stołach byłoby to również ważne dla urządzenia podrzędnego, ale w tym przypadku miało to zerowy wpływ na to urządzenie podrzędne dla tego jednego stołu, więc był to szybki sposób obejść ten problem. Usunięcie całej bazy danych byłoby znacznie większym projektem.
źródło
Dla mnie zadziałało:
mysqlfrm
z Oraclemysql-utitilies
** (ponieważ nie miałem innej kopii / kopii struktury) np .:/usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
MyTable
teraz utworzyłem tabelęMyTableB
o strukturze oryginalnej tabeli)RENAME TABLE `MyTableB` TO `MyTable`;
(uwaga, że to działa tylko jeśli ma nie byćinnodb_force_recovery
ustawiona wmy.cnf
)ALTER TABLE `MyTable` DISCARD TABLESPACE;
.ibd
plik (tylko plik .ibd, a nie plik .frm ) z powrotem do katalogu bazy danych mysql, z którego został pierwotnie przeniesiony (w tej chwili nie powinien istnieć plik .ibd, ponieważ zostanie on usunięty przezDISCARD TABLESPACE
Komenda)ALTER TABLE `MyTable` IMPORT TABLESPACE;
* Uruchomiłem ponownie mysql po tym kroku, ale nie jestem pewien, czy jest to wymagane
** Narzędzia mysql mogą wymagać instalacji w
mysql-connector-python
pierwszej kolejnościźródło
Straciłeś dane tabeli, ale rekord dotyczący tej tabeli nadal istnieje w „mysql / data / ibdata1”. Najłatwiejszym rozwiązaniem jest utworzenie tej tabeli w innej bazie danych, a następnie skopiowanie plików:
do własnego:
źródło