Tablo oluşturulamıyor, ancak tablo mevcut değil


11

my_userZaten var olan ama bir şekilde veritabanımdan yok olan bir tablo oluşturmak için bu adımları kullanıyorum 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)

Denedim # mysqladmin flush-tablesve yukarıdaki adımları tekrarladı ama yardımcı olmadı. Ayrıca, mysqlhizmet yeniden , ama hayır iyi.

Herhangi bir fikir? Google şu ana kadar başarısız oldu. Teşekkürler.

Fazladan bilgi:

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
Bir yerde yazım hatası olmadığından emin misin? Tablo oluşturduğunuzu söylüyorsunuz my_userama hata yaklaşık my_db.user...
mustaccio

@mustaccio, yep tablo adını my_user ile kısaltırken yazım hatası yaptı (orijinalin daha uzun ve kafa karıştırıcı bir adı var). Aslında CREATE TABLEkod Doctrine ORM kütüphanesi (PHP) tarafından üretilir.
noisebleed

Yani, bunlar gerçek isimler değil, sadece bize alay ediyorsun ...
mustaccio

InnoDB sözlüğünde kaydı terk ettiyseniz, aynı adda tablo oluşturmanıza izin vermez. Durumunuz gibi görünüyor, ancak daha fazla araştırmaya ihtiyaç var. Sahte my_user.frm ve my_user.ibd'yi koymayı ve tabloyu bırakmayı deneyin.
akuzminsky

Gerçek tablo adında garip bir karakter var mı (alfasayısal değil)? Rakam veya garip bir karakterle mi başlıyor?
ypercubeᵀᴹ

Yanıtlar:


7

InnoDB Mimarisi

InnoDB Mimarisi

ANALİZ

  • Her nasılsa, my_user.frmve my_user.ibddosyalarını kaybettiniz . Veri sözlüğünde yine de bu tablo için bir giriş vardır.
  • Sen koşamam DROP TABLE my_user;için çünkü Mysqld görünüyor my_user.frmilk. Bu hayır my_user.frmolduğu için, tablo düşürülemez.
  • Her ne kadar my_user.frmmevcut olmasa da , çalışamazsınız CREATE TABLE my_user ...çünkü mysqld tablo oluşturmanın uygun olduğunu düşünüyor ancak depolama motorunu etkiliyor. InnoDB "Zaten benim_kullancımın tablespace_id sahibiyim" diyor.

Tabloyu MyISAM kullanarak oluşturursanız bu olaylar dizisi kanıtlanabilir. mysqld izin verir. InnoDB'ye geçtiğinizde, söz konusu girişte hatalı olan veri sözlüğüne geri döner.

İki önerim var

ÖNERİ # 1

Artık bu ada sahip bir tablo oluşturmayın. Farklı bir tablo adı kullan

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;

Bu, uygulama kodunuzdaki tablo adını değiştirmenize neden olur

ÖNERİ # 2

Ben daha önce benim yazı InnoDB tablosunda bu sorunu ele SELECT ERROR 2006 (HY000) döner: MySQL sunucusu (elektrik kesintisi sonra) gitti


# 1 Harika cevap, detaylar için teşekkür ederim. # 2 Mysqldump (ed), mysqld'i durdurdu, ibdata1'i kaldırdı, sonra yeniden başlatıldı, ancak arka plan programının başarılı bir şekilde yeniden başlamasını sağlayamıyor. Neler olduğunu daha iyi anlamalıyız.
noisebleed

Tamam, şimdi her şey çalışıyor. Ayrıca kaldırmak zorunda kaldı ib_logfile0ve ib_logfile1(ile birlikte ibdata1). İçe aktarımdan sonra my_userherhangi bir sorun olmadan tablo oluşturabilirim . Teşekkürler Rolando!
noisebleed

Şimdi iki masa daha kaybettim. Yürütülen her sorguyu kaydediyorum ve bu tablolar kullanılarak kaldırılmadı DROP TABLE. Yanlış bir şeyler oluyor.
noisebleed

Teşekkürler. aynı sorun var. Veritabanımda 1 tablo eksik ve tabloyu oluşturamadığım için yedekten geri yükleyemiyorum.
Gigih Aji Ibrahim

5

Benzer bir sorun yaşadığım için çözümümü eklemek için.

TL; DR

  • Tabloyu, aynı yabancı anahtar belirtimi ile, ancak daha önce tablonun tuttuğu adla farklı bir adla yeniden oluşturun.
  • Ortaya çıkan tabloyu bırakın (ayrıca orijinal yetim yabancı anahtarı da düşürür)
  • Orijinal anahtarla veya yabancı anahtar olmadan tabloyu yeniden oluşturun

detay

Yabancı bir anahtarın daha önce düşürülmemesi nedeniyle ALTER TABLE ifadesinin başarısız olduğu kötü durumla karşılaştım. Bu, InnoDB veri sözlüğünde bazı tutarsızlıklara yol açtı (muhtemelen http://bugs.mysql.com/bug.php?id=58215 nedeniyle ).

İlgili soru burada: /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' ifadesinin './db/visits' olarak yeniden adlandırılması hatası (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.

# Sql-482c_8448f tablosunu ziyaretlere geri getiremediğim için, alter'den hemen önce yapılan bir yedeklemeden yeniden içe aktarmaya karar verdim. Ancak bu başarısız oldu. Soruşturma hakkında:

  • Kısıtlama BİLGİ_SCHEMA.TABLE_CONSTRAINTS ve BİLGİ_SCHEMA.STATISTICS'ten kaldırıldı
  • Ancak kısıtlama, hâlâ BİLGİ_SCHEMA.INNODB_SYS_FOREIGN konumunda görülüyordu;
  • Masa yoktu, bu yüzden yabancı anahtarı bırakamadım
  • Tabloyu hatasız oluşturamadım

SQL / Hatalar

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

Yabancı anahtar olmadan tabloyu yeniden oluşturmaya çalışmak ane hatasına 150 neden oldu

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

İle oluşturmaya çalışmak bir hataya neden oldu 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.

Sonunda yeni bir yabancı anahtar adı kullandım. Bunun çalışmasını beklemiyordum ama masanın yaratılmasına izin verdi.

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;

Bundan sonra tabloyu bırakarak, orijinal yabancı anahtar adıyla bir içe aktarmaya izin vererek BİLGİ_SCHEMA.INNODB_SYS_FOREIGN içindeki hatalı kayıt kaldırıldı.


1

Bunun etrafında basit bir yol vardır, ancak kuşkusuz, bazı durumlarda bunu yapmak istemeyebilirsiniz. Bu sorun InnoDB iç referansından kaynaklandığından, bu tabloyu yalnızca farklı bir depolama motoru kullanarak aynı ada, aynı sütunlara sahip olarak oluşturabilirsiniz. Ben bir MySQL slave üzerinde bu koştu ve çoğaltmak ustası InnoDB olmasına rağmen, bu bir tablo MyISAM ile yeniden oluşturdu ve geri almak ve çalıştırmak mümkün. Özellikle master üzerindeki depolama motorum için InnoDB'yi seçtim ve bazı tablolarda, köle üzerinde de önemli olurdu, ancak bu durumda, bu tek tablo için bu köle üzerinde sıfır etkisi oldu, bu yüzden hızlı bir yol oldu bu sorunu çözmek için. Veritabanının tamamını bırakmak çok daha büyük bir proje olurdu.


0

Benim için işe yarayan şuydu:

  • önce .frm ve .ibd dosyalarını başka bir dizine taşıyın, örneğin / tmp / tablebackup *
  • şimdi tablo yapısını mysqlfrmOracle'ın mysql-utitilies** kullanarak .frm dosyasından ayıklanıyor (çünkü yapının başka bir kopyası / yedeği yoktu) örneğin:/usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
  • orijinal tablonun yapısıyla ancak farklı bir adla yeni bir tablo oluşturmak (örneğin diyelim ki sorunlu MyTabletablo şimdi MyTableBorijinal tablonun yapısına sahip bir tablo oluşturduğum )
  • Bir sonraki MySQL içinden orijinal adının tabloyu yeniden adlandırmak, örneğin: RENAME TABLE `MyTableB` TO `MyTable`;(bu sadece do çalışır eğer notu değil gelmiş innodb_force_recoveryGözlerinde farklı set my.cnf)
  • şimdi mysql çalıştırmak: ALTER TABLE `MyTable` DISCARD TABLESPACE;
  • daha sonra orijinal .ibddosyayı (.frm dosyasını değil , yalnızca .ibd dosyasını ) orijinal olarak taşındığı mysql veritabanı dizinine kopyalayın (şu anda varolan bir .ibd dosyası olmamalıdır, çünkü DISCARD TABLESPACEkomutu)
  • ve şimdi koş ALTER TABLE `MyTable` IMPORT TABLESPACE;

* Bu adımdan sonra mysql'yi yeniden başlattım ancak bunun gerekli olduğundan emin değilim

** mysql-utilities mysql-connector-pythonönce kurulum gerektirebilir


0

Tablo verilerini kaybettiniz, ancak bu tablo hakkındaki kayıt hala "mysql / data / ibdata1" içinde var. En kolay çözüm, bu tabloyu başka bir veritabanında oluşturmak ve daha sonra dosyaları kopyalamaktır:

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

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

kendi başına:

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

mysql/data/**yours_database**/my_user.ibd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.