Không thể tạo bảng, nhưng bảng không tồn tại


11

Tôi đang sử dụng các bước này để tạo một bảng my_user, đã tồn tại nhưng bằng cách nào đó đã biến mất khỏi cơ sở dữ liệu của tôi 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)

Đã thử # mysqladmin flush-tablesvà lặp lại các bước trên nhưng nó không hữu ích. Ngoài ra, khởi động lại mysqldịch vụ, nhưng không tốt.

Có ý kiến ​​gì không? Google đã làm tôi thất bại cho đến nay. Cảm ơn.

Thông tin thêm:

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
Bạn có chắc là bạn không mắc lỗi đánh máy ở đâu đó không? Bạn nói rằng bạn đang tạo bảng my_usernhưng lỗi là về my_db.user...
mustaccio

@mustaccio, yep đã mắc lỗi đánh máy khi rút ngắn tên bảng thành my_user (bản gốc có tên dài hơn, khó hiểu). Trên thực tế, CREATE TABLEmã được tạo bởi thư viện Doctrine ORM (PHP).
ồn ào

Vì vậy, đây không phải là tên thật, bạn chỉ đang trêu chọc chúng tôi ...
mustaccio

nếu bạn đã bỏ bản ghi trong từ điển InnoDB, nó sẽ không cho phép bạn tạo bảng có cùng tên. Hình như trường hợp của bạn, nhưng cần điều tra thêm. Hãy thử đặt my_user.frm và my_user.ibd giả và thả bảng.
akuzminsky

Tên bảng thực tế có bất kỳ ký tự lạ (không phải chữ và số) không? Nó bắt đầu bằng một chữ số hoặc một ký tự kỳ lạ?
ypercubeᵀᴹ

Câu trả lời:


6

Kiến trúc InnoDB

Kiến trúc InnoDB

PHÂN TÍCH

  • Bằng cách nào đó, bạn bị mất my_user.frmmy_user.ibdcác tập tin. Từ điển dữ liệu vẫn có một mục cho bảng đó.
  • Bạn không thể chạy DROP TABLE my_user;vì mysqld tìm kiếm my_user.frmđầu tiên. Vì điều này là không my_user.frm, bảng không thể được bỏ.
  • Mặc dù my_user.frmkhông tồn tại, bạn không thể chạy CREATE TABLE my_user ...vì mysqld cho rằng việc tạo bảng là ổn nhưng sau đó lại chuyển sang công cụ lưu trữ. InnoDB nói "Tôi đã có bảngpace_id của my_user đã đăng ký".

Chuỗi sự kiện này có thể được chứng minh nếu bạn tạo bảng bằng MyISAM. mysqld sẽ cho phép nó. Khi bạn chuyển sang InnoDB, nó sẽ quay lại từ điển dữ liệu, lỗi này trong một mục nhập đó.

Tôi có hai gợi ý

BỀN VỮNG # 1

Đừng tạo bảng với tên đó nữa. Sử dụng tên bảng khác

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;

Điều này sẽ dẫn đến việc bạn thay đổi tên bảng trong mã ứng dụng của bạn

BỀN VỮNG # 2

Tôi đã xử lý vấn đề này trước đây trong bài đăng của mình Bảng InnoDB CHỌN trả về ERROR 2006 (HY000): Máy chủ MySQL đã biến mất (sau khi mất điện)


# 1 Câu trả lời tuyệt vời, cảm ơn bạn đã chi tiết. # 2 Mysqldump (ed), đã dừng mysqld, xóa ibdata1, sau đó khởi động lại nhưng không thể lấy daemon để bắt đầu lại thành công. Cần hiểu rõ hơn những gì đang diễn ra.
ồn ào

Ok, mọi thứ đang hoạt động. Phải loại bỏ ib_logfile0ib_logfile1(cùng với ibdata1). Sau khi nhập tôi có thể tạo my_userbảng mà không có bất kỳ vấn đề. Cảm ơn Rolando!
ồn ào

Tôi đã mất hai bảng khác bây giờ. Tôi đang ghi lại mọi truy vấn đã thực hiện và các bảng đó không bị xóa bằng cách sử dụng DROP TABLE. Một cái gì đó sai đang xảy ra.
ồn ào

5

Chỉ cần thêm giải pháp của tôi là tôi đã có một vấn đề tương tự.

TL; DR

  • Tạo lại bảng với cùng một đặc tả khóa ngoại nhưng với một tên khác như trước đó được giữ bởi bảng.
  • Bỏ bảng kết quả (cũng sẽ bỏ khóa ngoại gốc mồ côi gốc)
  • Bảng tái tạo với bản gốc hoặc không có khóa ngoại

Chi tiết

Tôi gặp phải tình huống khó chịu khi một câu lệnh ALTER TABLE thất bại do khóa ngoại không bị hủy trước đó. Điều này dẫn đến một số mâu thuẫn trong từ điển dữ liệu InnoDB (có thể là do http://bugs.mysql.com/orms.php?id=58215 ).

Câu hỏi liên quan ở đây: /programming/16857451/error-in-forign-key-constraint-on-a-droped-table

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

Lỗi khi đổi tên './db/#sql-482c_8448f' thành './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.

Vì tôi không thể khôi phục bảng # sql-482c_8448f cho các lượt truy cập, tôi quyết định nhập lại nó từ bản sao lưu được thực hiện ngay trước khi thay đổi. Tuy nhiên điều này đã thất bại. Về điều tra:

  • Ràng buộc đã bị xóa khỏi Information_SCHema.TABLE_CONSTRAINTS và Information_SCHema.STATISTICS
  • Nhưng các ràng buộc vẫn có thể nhìn thấy trong Information_SCHema.INNODB_SYS_FOREIGN;
  • Bảng không tồn tại nên tôi không thể bỏ khóa ngoại
  • Tôi không thể tạo bảng mà không có lỗi

SQL / lỗi

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

Cố gắng tạo lại bảng mà không có khóa ngoại gây ra lỗi ane 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

Cố gắng tạo ra nó gây ra lỗi 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.

Cuối cùng, tôi đã sử dụng một tên khóa nước ngoài mới. Tôi không mong đợi nó hoạt động nhưng nó cho phép tạo bảng.

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;

Chỉ cần bỏ bảng sau đó đã xóa bản ghi errant trong THÔNG TIN_SCHema.INNODB_SYS_FOREIGN, cho phép nhập với tên khóa ngoại gốc.


1

Có một cách đơn giản xung quanh điều này, mặc dù phải thừa nhận, trong một số trường hợp nhất định bạn có thể không muốn làm điều này. Vì vấn đề này xuất phát từ một tham chiếu nội bộ của InnoDB, bạn chỉ cần tạo bảng này có cùng tên, cùng cột, chỉ sử dụng một công cụ lưu trữ khác. Tôi đã gặp vấn đề này trên một nô lệ MySQL và mặc dù chủ nhân mà tôi đang sao chép là InnoDB, tôi đã tạo lại một bảng này với MyISAM và có thể sao lưu và chạy. Tôi đặc biệt chọn InnoDB cho công cụ lưu trữ của mình trên máy chủ và trên một số bảng, điều đó cũng quan trọng đối với nô lệ, nhưng trong trường hợp này, nó không ảnh hưởng đến nô lệ này cho một bảng này, vì vậy đó là cách nhanh chóng để giải quyết vấn đề này Bỏ toàn bộ cơ sở dữ liệu sẽ là một dự án lớn hơn nhiều.


0

Những gì làm việc cho tôi là:

  • đầu tiên di chuyển các tệp .frm và .ibd sang một thư mục khác, ví dụ / tmp / tablebackup *
  • hiện trích xuất cấu trúc bảng từ tệp .frm bằng cách sử dụng mysqlfrmtừ mysql-utitilies** của Oracle (vì tôi không có bản sao / sao lưu cấu trúc nào khác), vd:/usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
  • tạo một bảng mới với cấu trúc của bảng gốc nhưng với một tên khác (ví dụ: giả sử bảng có vấn đề MyTablethì bây giờ tôi đã tạo một bảng MyTableBcó cấu trúc của bảng gốc)
  • sau đổi tên bảng để tên gốc từ bên trong mysql, ví dụ: RENAME TABLE `MyTableB` TO `MyTable`;(lưu ý rằng điều này chỉ hoạt động nếu bạn không đã innodb_force_recoverythiết lập trong của bạn my.cnf)
  • bây giờ trong mysql chạy: ALTER TABLE `MyTable` DISCARD TABLESPACE;
  • sau đó sao chép .ibdtệp gốc (chỉ tệp .ibd, không phải tệp .frm ) trở lại thư mục cơ sở dữ liệu mysql nơi nó được di chuyển từ đó (không nên có tệp .ibd hiện tại vì bị xóa bởi DISCARD TABLESPACEchỉ huy)
  • và bây giờ chạy ALTER TABLE `MyTable` IMPORT TABLESPACE;

* Tôi đã khởi động lại mysql sau bước này nhưng không chắc chắn điều này là bắt buộc

** tiện ích mysql có thể yêu cầu cài đặt mysql-connector-pythontrước


0

Bạn đã mất dữ liệu bảng, nhưng bản ghi về bảng này vẫn tồn tại trong "mysql / data / ibdata1". Giải pháp đơn giản nhất là tạo bảng này trong một số cơ sở dữ liệu khác và sau đó sao chép tệp:

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

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

cho riêng bạn:

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

mysql/data/**yours_database**/my_user.ibd
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.