ไม่สามารถสร้างตาราง แต่ไม่มีตาราง


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รหัสนั้นสร้างขึ้นโดย Doctrine ORM library (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 กล่าวว่า "ฉันมี 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 เลือกคืนข้อผิดพลาด 2006 (HY000): เซิร์ฟเวอร์ MySQL ได้หายไป (หลังจากไฟฟ้าดับ)


# 1 คำตอบที่ดีขอบคุณสำหรับรายละเอียด # 2 Mysqldump (ed), หยุด mysqld, ลบ ibdata1, จากนั้นรีสตาร์ท แต่ไม่สามารถให้ daemon เริ่มต้นได้สำเร็จอีกครั้ง ต้องเข้าใจให้ดียิ่งขึ้นว่าเกิดอะไรขึ้น
กึกก้อง

ตกลงทุกอย่างทำงานตอนนี้ ยังต้องลบib_logfile0และib_logfile1(พร้อมด้วยibdata1) หลังจากนำเข้าฉันสามารถสร้างmy_userตารางโดยไม่มีปัญหาใด ๆ ขอบคุณ Rolando!
กึกก้อง

ฉันทำตารางอื่นสองตารางหายไปแล้ว DROP TABLEฉันบันทึกทุกแบบสอบถามการดำเนินการและตารางเหล่านั้นไม่ได้ถูกลบออกโดยใช้ มีบางอย่างผิดปกติเกิดขึ้น
กึกก้อง

ขอบคุณ มีปัญหาที่แน่นอนเหมือนกัน 1 ตารางในฐานข้อมูลของฉันหายไปและฉันไม่สามารถเรียกคืนจากการสำรองข้อมูลได้เพราะฉันไม่สามารถสร้างตารางได้
Gigih Aji Ibrahim

5

เพียงเพิ่มโซลูชันของฉันเนื่องจากฉันมีปัญหาที่คล้ายกัน

TL; DR

  • สร้างตารางใหม่ด้วยข้อมูลจำเพาะ foreign key เดียวกัน แต่ใช้ชื่ออื่นที่จัดขึ้นก่อนหน้าโดยตาราง
  • ดร็อปตารางผลลัพธ์ (จะดรอปคีย์เด็กกำพร้าต้นฉบับ)
  • สร้างตารางใหม่ด้วยรหัสต้นฉบับหรือไม่มีรหัสต่างประเทศ

รายละเอียด

ฉันวิ่งเข้าไปในสถานการณ์ที่น่ารังเกียจที่คำสั่ง 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' (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 ไปยังการเข้าชมได้ฉันจึงตัดสินใจนำเข้าอีกครั้งจากการสำรองข้อมูลที่กระทำก่อนการเปลี่ยนแปลง อย่างไรก็ตามเรื่องนี้ล้มเหลว ในการสอบสวน:

  • ข้อ จำกัด ถูกลบออกจาก 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 MySQL และถึงแม้ว่าต้นแบบที่ฉันจำลองมาจากนั้นก็คือ InnoDB แต่ฉันก็สร้างตารางนี้ขึ้นใหม่ด้วย MyISAM และสามารถกลับมาทำงานได้ ฉันเลือก InnoDB เป็นพิเศษสำหรับเอ็นจิ้นการจัดเก็บข้อมูลของฉันบนมาสเตอร์และในบางตารางมันจะมีความสำคัญกับทาสเช่นกัน แต่ในกรณีนี้มันไม่มีผลกระทบใด ๆ ต่อทาสนี้สำหรับตารางนี้ดังนั้นมันจึงเป็นวิธีที่รวดเร็ว เพื่อแก้ไขปัญหานี้ การทิ้งฐานข้อมูลทั้งหมดจะเป็นโครงการที่ใหญ่กว่ามาก


0

สิ่งที่ทำงานให้ฉันคือ:

  • ก่อนอื่นให้ย้ายไฟล์. frm และ. ibd ไปยัง dir อื่นเช่น / tmp / tablebackup *
  • ตอนนี้แยกโครงสร้างตารางจากไฟล์. frm ที่ใช้mysqlfrmจาก Oracle ของ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-Utilities อาจต้องติดตั้ง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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.