Tidak dapat membuat tabel, tetapi tabel tidak ada

11

Saya menggunakan langkah-langkah ini untuk membuat tabel my_user, yang sudah ada tetapi entah bagaimana lenyap dari database saya 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)

Mencoba # mysqladmin flush-tablesdan mengulangi langkah-langkah di atas tetapi tidak membantu. Juga, restart mysqllayanan, tetapi tidak bagus.

Ada ide? Google telah mengecewakan saya sejauh ini. Terima kasih.

Informasi tambahan:

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")
berisik
sumber
1
Apakah Anda yakin tidak memiliki kesalahan ketik di suatu tempat? Anda mengatakan Anda membuat tabel my_usertetapi kesalahannya adalah tentang my_db.user...
mustaccio
@mustaccio, ya membuat salah ketik ketika ketika memperpendek nama tabel menjadi my_user (aslinya memiliki nama yang lebih panjang dan membingungkan). Sebenarnya CREATE TABLEkode ini dihasilkan oleh perpustakaan ORM Doctrine (PHP).
noisebleed
Jadi, ini bukan nama sebenarnya, Anda hanya menggoda kami ...
mustaccio
jika Anda telah meninggalkan catatan dalam kamus InnoDB itu tidak akan membiarkan Anda membuat tabel dengan nama yang sama. Sepertinya kasus Anda, tetapi perlu penyelidikan lebih lanjut. Cobalah untuk meletakkan my_user.frm dan my_user.ibd palsu dan letakkan tabelnya.
akuzminsky
Apakah nama tabel sebenarnya memiliki karakter aneh (bukan alfanumerik)? Apakah ini dimulai dengan angka atau karakter aneh?
ypercubeᵀᴹ

Jawaban:

6

Arsitektur InnoDB

Arsitektur InnoDB

ANALISIS

  • Entah bagaimana, Anda kehilangan my_user.frmdan my_user.ibdfile. Kamus data masih memiliki entri untuk tabel itu.
  • Anda tidak dapat menjalankan DROP TABLE my_user;karena mysqld mencari yang my_user.frmpertama. Karena ini tidak my_user.frm, tabel tidak dapat dijatuhkan.
  • Meskipun my_user.frmtidak ada, Anda tidak dapat menjalankan CREATE TABLE my_user ...karena mysqld berpikir tidak masalah untuk membuat tabel tetapi kemudian beralih ke mesin penyimpanan. InnoDB mengatakan "Saya sudah memiliki tablespace_id dari my_user terdaftar".

Urutan acara ini dapat dibuktikan jika Anda membuat tabel menggunakan MyISAM. mysqld akan mengizinkannya. Setelah Anda beralih ke InnoDB, langsung kembali ke kamus data, yang salah pada satu entri itu.

Saya punya dua saran

SARAN # 1

Jangan membuat tabel dengan nama itu lagi. Gunakan nama tabel yang berbeda

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;

Ini akan mengakibatkan Anda mengubah nama tabel dalam kode aplikasi Anda

SARAN # 2

Saya telah berurusan dengan masalah ini sebelumnya di tabel InnoDB posting saya SELECT return ERROR 2006 (HY000): Server MySQL telah hilang (setelah listrik padam)

RolandoMySQLDBA
sumber
# 1 Jawaban yang bagus, terima kasih untuk detailnya. # 2 Mysqldump (ed), menghentikan mysqld, menghapus ibdata1, kemudian memulai kembali tetapi tidak dapat membuat daemon untuk memulai lagi dengan sukses. Perlu lebih memahami apa yang terjadi.
noisebleed
Ok, semuanya bekerja sekarang. Harus juga menghapus ib_logfile0dan ib_logfile1(bersamaan dengan ibdata1). Setelah impor saya bisa membuat my_usertabel tanpa masalah. Rolando terima kasih!
noisebleed
Saya telah kehilangan dua meja lainnya sekarang. Saya merekam setiap kueri yang dieksekusi dan tabel itu tidak dihapus menggunakan DROP TABLE. Sesuatu yang salah sedang terjadi.
noisebleed
5

Hanya untuk menambahkan solusi saya karena saya punya masalah yang sama.

TL; DR

  • Buat kembali meja dengan spesifikasi kunci asing yang sama tetapi dengan nama yang berbeda seperti yang sebelumnya dipegang oleh meja.
  • Jatuhkan tabel yang dihasilkan (juga akan menjatuhkan kunci asing asli anak yatim)
  • Buat kembali meja dengan kunci asing atau tanpa kunci asing

Detail

Saya mengalami situasi yang tidak menyenangkan di mana pernyataan ALTER TABLE gagal karena kunci asing tidak dijatuhkan sebelumnya. Hal ini menyebabkan beberapa ketidakkonsistenan dalam kamus data InnoDB (mungkin karena http://bugs.mysql.com/bug.php?id=58215 ).

Pertanyaan terkait di sini: /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  ;

Kesalahan saat mengubah nama './db/#sql-482c_8448f' menjadi './db/visits' (errno: 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.

Karena saya tidak dapat memulihkan tabel # sql-482c_8448f menjadi kunjungan, saya memutuskan untuk menggantinya dari cadangan yang dilakukan tepat sebelum perubahan. Namun ini gagal. Sedang diselidiki:

  • Kendala telah dihapus dari INFORMATION_SCHEMA.TABLE_CONSTRAINTS dan INFORMATION_SCHEMA.STATISTICS
  • Namun kendala masih terlihat di INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
  • Meja tidak ada sehingga saya tidak bisa menjatuhkan kunci asing
  • Saya tidak bisa membuat tabel tanpa kesalahan

SQL / Kesalahan

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 |
+-----------------------------------+-----------+------------------------+--------+------+

Mencoba membuat ulang tabel tanpa kunci asing menyebabkan kesalahan 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

Mencoba membuatnya dengan menyebabkan kesalahan 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.

Akhirnya saya menggunakan nama kunci asing baru. Saya tidak berharap ini berfungsi tetapi memungkinkan tabel dibuat.

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;

Cukup dengan menjatuhkan tabel setelah itu menghapus catatan yang salah di INFORMATION_SCHEMA.INNODB_SYS_FOREIGN, memungkinkan impor dengan nama kunci asing asli.

Markus C
sumber
1

Ada satu cara sederhana untuk mengatasi hal ini, walaupun harus diakui, dalam keadaan tertentu Anda mungkin tidak ingin melakukan ini. Karena masalah ini berasal dari referensi internal InnoDB, Anda cukup membuat tabel ini dengan nama yang sama, kolom yang sama, hanya menggunakan mesin penyimpanan yang berbeda. Saya menemukan ini pada slave MySQL, dan meskipun master yang saya replikasi adalah InnoDB, saya membuat ulang tabel ini dengan MyISAM dan dapat bangkit kembali dan berjalan. Saya secara khusus memilih InnoDB untuk mesin penyimpanan saya pada master, dan pada beberapa tabel, itu akan menjadi penting pada slave juga, tetapi dalam kasus ini, itu tidak berdampak pada slave ini untuk tabel yang satu ini, jadi itu cara cepat untuk mengatasi masalah ini. Menjatuhkan seluruh basis data akan menjadi proyek yang jauh lebih besar.

Pengembang Real Estat
sumber
0

Apa yang berhasil untuk saya adalah:

  • pertama-tama pindahkan file .frm dan .ibd ke direktori lain, misalnya / tmp / tablebackup *
  • sekarang mengekstraksi struktur tabel dari file .frm menggunakan mysqlfrmdari Oracle mysql-utitilies** (karena saya tidak punya salinan / cadangan dari struktur) misalnya:/usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
  • buat tabel baru dengan struktur tabel asli tetapi dengan nama yang berbeda (mis. katakanlah tabel dengan masalah ini MyTablemaka sekarang saya membuat tabel MyTableBdengan struktur tabel asli)
  • selanjutnya mengubah nama tabel untuk nama asli dari dalam mysql, misalnya: RENAME TABLE `MyTableB` TO `MyTable`;(catatan bahwa ini hanya bekerja jika Anda tidak memiliki innodb_force_recoverydiatur dalam Anda my.cnf)
  • sekarang dalam menjalankan mysql: ALTER TABLE `MyTable` DISCARD TABLESPACE;
  • kemudian salin .ibdfile asli (hanya file .ibd, bukan file .frm) kembali ke dir database mysql tempat asalnya dipindahkan (seharusnya tidak ada file .ibd yang ada saat ini karena itu akan dihapus oleh DISCARD TABLESPACEperintah)
  • dan sekarang jalankan ALTER TABLE `MyTable` IMPORT TABLESPACE;

* Saya memulai kembali mysql setelah langkah ini tetapi tidak yakin ini diperlukan

** mysql-utilities mungkin perlu menginstal mysql-connector-pythonterlebih dahulu

Arthur
sumber
0

Anda kehilangan data tabel, tetapi catatan tentang tabel ini masih ada di "mysql / data / ibdata1". Solusi termudah adalah membuat tabel ini di beberapa database lain dan kemudian salin file:

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

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

untuk Anda sendiri:

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

mysql/data/**yours_database**/my_user.ibd
Hevyweb
sumber