Не могу создать таблицу, но таблица не существует

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")
noisebleed
источник
1
Вы уверены, что у вас нет опечатки где-нибудь? Вы говорите, что создаете таблицу, my_userно ошибка о my_db.user...
mustaccio
@mustaccio, yep произвела опечатку, когда сокращала имя таблицы до my_user (оригинал имеет более длинное, запутанное имя). На самом деле CREATE TABLEкод генерируется библиотекой Doctrine ORM (PHP).
шумит
Таким образом, это не настоящие имена, вы просто дразните нас ...
mustaccio
Если вы оставили запись в словаре InnoDB, она не позволит вам создать таблицу с тем же именем. Похоже на ваше дело, но нуждается в дополнительном расследовании. Попробуйте поставить fake my_user.frm и my_user.ibd и удалить таблицу.
Акузминский
Имеет ли фактическое имя таблицы какой-либо странный символ (не буквенно-цифровой)? Это начинается с цифры или странного символа?
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 говорит: «У меня уже есть зарегистрированный tablespace_id 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 возвращает ERROR 2006 (HY000): сервер MySQL пропал (после отключения питания)

RolandoMySQLDBA
источник
# 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 в другой каталог, например / 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
Hevyweb
источник