Неможливо створити таблицю, але таблиця не існує


11

Я використовую ці кроки для створення таблиці my_user, яка вже існувала, але якось зникла з моєї бази даних 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)

Спробував # mysqladmin flush-tablesі повторив наведені вище кроки, але це було не корисно. Також перезапустили mysqlпослугу, але нічого поганого.

Будь-які ідеї? Google поки що мене провалив. Дякую.

Додаткова інформація:

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")

1
Ви впевнені, що десь не маєте друку? Ви кажете, що ви створюєте таблицю, my_userале помилка приблизно my_db.user...
mustaccio

@mustaccio, yep зробив помилку, коли скорочував ім'я таблиці до my_user (оригінал має довше, заплутане ім'я). Насправді CREATE TABLEкод генерується бібліотекою ORM доктрин (PHP).
шумили

Отже, це не справжні імена, ви нас просто дражнили ...
mustaccio

якщо ви покинули запис у словнику InnoDB, він не дозволить вам створити таблицю з таким же ім'ям. Схоже на вашу справу, але потребує більшого розслідування. Спробуйте поставити підроблені my_user.frm та my_user.ibd і опустити стіл.
akuzminsky

Чи має фактична назва таблиці якийсь дивний характер (не буквено-цифровий)? Починається це з цифри чи дивного символу?
ypercubeᵀᴹ

Відповіді:


7

Архітектура InnoDB

Архітектура InnoDB

АНАЛІЗ

  • Якось ви втратили my_user.frmі my_user.ibdфайли. У словнику даних все ще є запис для цієї таблиці.
  • Ви не можете запустити, DROP TABLE my_user;тому що mysqld шукає my_user.frmперше. Оскільки це ні my_user.frm, таблицю не можна скидати.
  • Хоча my_user.frmце не існує, ви не можете запустити, CREATE TABLE my_user ...тому що mysqld вважає, що це добре, щоб створити таблицю, але потім відкладається на механізм зберігання даних. InnoDB каже: "У мене вже зареєстрований табличний пробіл my_user".

Цю послідовність подій можна довести, якщо створити таблицю за допомогою MyISAM. mysqld дозволить це. Після переходу на InnoDB він повертається до словника даних, який є несправним для цього запису.

У мене дві пропозиції

ПРЕДЛОЖЕННЯ №1

Більше не створюйте таблицю з таким ім'ям. Використовуйте іншу назву таблиці

CREATE TABLE my_usertable (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;

Це призведе до зміни назви таблиці у коді програми

ПРЕДЛОЖЕННЯ №2

Я вирішував цю проблему раніше, ніж у своїй таблиці InnoDB SELECT повертає ПОМИЛКА 2006 (HY000): сервер MySQL пішов (після відключення електроенергії)


№1 Чудова відповідь, дякую за деталі. # 2 Mysqldump (ed), зупинив mysqld, видалив ibdata1, потім перезапустив, але неможливо змусити демон знову успішно запуститися. Потрібно краще зрозуміти, що відбувається.
шумило

Гаразд, все працює зараз. Довелося також видалити ib_logfile0і ib_logfile1(разом з ibdata1). Після імпорту я міг створити my_userтаблицю без проблем. Дякую Роландо!
безшумний

Зараз я втратив дві інші таблиці. Я записую кожен виконаний запит, і ці таблиці не видалено за допомогою DROP TABLE. Щось відбувається не так.
шумили

Дякую. мають таку ж точну проблему. 1 таблиця в моїй базі даних відсутня, і я не можу відновити її з резервного копіювання, оскільки я не можу створити таблицю.
Гігіх Аджі Ібрагім

5

Просто додати своє рішення, як у мене була подібна проблема.

TL; DR

  • Відтворіть таблицю з тією ж специфікацією зовнішнього ключа, але з іншою назвою, яку раніше містила таблиця.
  • Опустіть отриману таблицю (також випаде оригінальний іноземний ключ-сирота)
  • Відтворити таблицю з оригінальним або відсутнім зовнішнім ключем

Деталь

Я зіткнувся з неприємною ситуацією, коли заява ALTER TABLE не вдалася через те, що зовнішній ключ не був відпущений раніше. Це призвело до певних невідповідностей у словнику даних InnoDB (можливо, через http://bugs.mysql.com/bug.php?id=58215 ).

Тут пов’язане запитання: /programming/16857451/error-in-foreign-key-constraint-on-a-droped-table

mysql> ALTER TABLE `visits` CHANGE COLUMN `variation_visitor_id` `variation_visitor_id` INT(11) NOT NULL  ;

Помилка перейменування './db/#sql-482c_8448f' в './db/visits' (помилка: 150)

mysql> SHOW ENGINE INNODB STATUS;

Error in foreign key constraint of table db/visits:
 FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html 
for correct foreign key definitippon.

Оскільки я не зміг відновити таблицю # sql-482c_8448f для відвідувань, я вирішив повторно імпортувати її з резервної копії, зробленої безпосередньо перед зміною. Однак це не вдалося. На слідстві:

  • Обмеження було знято з INFORMATION_SCHEMA.TABLE_CONSTRAINTS та INFORMATION_SCHEMA.STATISTICS
  • Але обмеження все ще було видно в INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
  • Стіл не існував, тому я не міг скинути іноземний ключ
  • Я не міг створити таблицю без помилок

SQL / Помилки

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN WHERE ID='db/fk_visits_variations_visitors1';

+-----------------------------------+-----------+------------------------+--------+------+
| ID                                | FOR_NAME  | REF_NAME               | N_COLS | TYPE |
+-----------------------------------+-----------+------------------------+--------+------+
| db/fk_visits_variations_visitors1 | db/visits | db/variations_visitors |      1 |   48 |
+-----------------------------------+-----------+------------------------+--------+------+

Спроба відтворити таблицю без стороннього ключа викликала помилку ане 150

mysql>

SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;

CREATE TABLE `visits` (
  `id` INT(11) NOT NULL AUTO_INCREMENT  ,
  `variation_visitor_id` INT(11) NOT NULL  ,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;

ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 150)

mysql> SHOW ENGINE INNODB STATUS;

Error in foreign key constraint of table db/visits:
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_visits_variations_visitors1" FOREIGN KEY ("variation_visitor_id") REFERENCES "variations_visitors" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION

Спроба створити його за допомогою викликала помилку 121

mysql>

SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;

CREATE TABLE `visits` (
  `id` INT(11) NOT NULL AUTO_INCREMENT  ,
  `variation_visitor_id` INT(11) NOT NULL  ,
  PRIMARY KEY (`id`),
  KEY `fk_visits_variations_visitors1` (`variation_visitor_id`),
  CONSTRAINT `fk_visits_variations_visitors1` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;

ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 121)

mysql> SHOW ENGINE INNODB STATUS;

Error in foreign key constraint creation for table `db`.`visits`.
A foreign key constraint of name `db`.`fk_visits_variations_visitors1`
already exists. (Note that internally InnoDB adds 'databasename'
in front of the user-defined constraint name.)
Note that InnoDB's FOREIGN KEY system tables store
constraint names as case-insensitive, with the
MySQL standard latin1_swedish_ci collation. If you
create tables or databases whose names differ only in
> the character case, then collisions in constraint
names can occur. Workaround: name your constraints
explicitly with unique names.

Врешті-решт я використав нове ім'я іноземного ключа. Я не очікував, що це спрацює, але це дозволило створити таблицю.

mysql>

SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;

CREATE TABLE `visits` (
  `id` INT(11) NOT NULL AUTO_INCREMENT  ,
  `variation_visitor_id` INT(11) NOT NULL  ,
  PRIMARY KEY (`id`),
  KEY `fk_visits_variations_visitors2` (`variation_visitor_id`),
  CONSTRAINT `fk_visits_variations_visitors2` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;

Просто скинувши таблицю, після цього видалить запис помилки в INFORMATION_SCHEMA.INNODB_SYS_FOREIGN, що дозволить імпортувати оригінальне ім'я іноземного ключа.


1

Існує один простий спосіб цього, хоча, правда, за певних обставин ви, можливо, не захочете цього робити. Оскільки ця проблема випливає з внутрішньої посилання InnoDB, ви можете просто створити цю таблицю з тим самим іменем, тими ж стовпцями, лише використовуючи інший механізм зберігання даних. Я наткнувся на це на підлеглому MySQL, і, хоча майстер, з якого я реплікував, був InnoDB, я створив цю одну таблицю разом з MyISAM і зміг повернутися до роботи. Я спеціально вибрав InnoDB для свого механізму зберігання даних на майстрі, а для деяких таблиць це було б важливо і для підлеглого, але в цьому випадку він мав нульовий вплив на цей підлеглий для цієї однієї таблиці, тому це був швидкий шлях щоб обійти це питання. Видалення всієї бази даних було б набагато більшим проектом.


0

Що для мене працювало:

  • спочатку перемістіть файли .frm та .ibd до іншого dir, наприклад / tmp / tablebackup *
  • тепер витягуємо структуру таблиці з .frm-файлу, використовуючи ** ** mysqlfrmOracle mysql-utitilies(оскільки у мене не було іншої копії / резервної копії структури), наприклад:/usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
  • створити нову таблицю зі структурою оригінальної таблиці, але з іншою назвою (наприклад, скажімо, таблиця з проблемою - MyTableтоді я створив таблицю MyTableBз початковою структурою таблиці)
  • Наступний перейменувати таблицю з початковим ім'ям з MySQL, наприклад: RENAME TABLE `MyTableB` TO `MyTable`;(зверніть увагу , що це працює тільки , якщо ви НЕ були innodb_force_recoveryвстановити в вашому my.cnf)
  • тепер у запуску mysql: ALTER TABLE `MyTable` DISCARD TABLESPACE;
  • потім скопіювати початковий .ibdфайл (тільки .ibd файл, а НЕ файлової .frm) назад в директорію бази даних MySQL , де він спочатку був переміщений з (не повинно бути існуючий файл .ibd в цей момент , тому що отримує видалити з допомогою DISCARD TABLESPACEкомандування)
  • а тепер біжи ALTER TABLE `MyTable` IMPORT TABLESPACE;

* Я перезапустив mysql після цього кроку, але не впевнений, що це потрібно

** Утиліти mysql можуть потребувати встановлення mysql-connector-pythonспочатку


0

Ви втратили дані таблиці, але запис про цю таблицю все ще існує у "mysql / data / ibdata1". Найпростіше рішення створити цю таблицю в якійсь іншій базі даних, а потім скопіювати файли:

mysql/data/**dummy_database**/my_user.frm

mysql/data/**dummy_database**/my_user.ibd

до власного:

mysql/data/**yours_database**/my_user.frm

mysql/data/**yours_database**/my_user.ibd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.