如何修复在 AWS RDS 上从创建 (errno: -1) 锁定 table 名称的 InnoDB 损坏?

How do I fix InnoDB corruption locking a table name from creation (errno: -1) on AWS RDS?

提示不要 运行 ALTER MySQL Workbench 语句] 用于 "Standard TCP/IP over SSH" 连接。 shell 进入服务器并从那里 运行 ALTER 更好。这样,如果您失去与服务器的连接,ALTER 仍应完成其工作。

我正在尝试在我昨天尝试创建的数据库中创建一个新的 table。问题是,我的互联网一直在微辍学中失去连接。我相信这些故障之一发生在我创建 table 时,现在当我尝试使用 完全相同的名称 创建 table 时:

CREATE TABLE IF NOT EXISTS `adstudio`.`data_feed_param` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

我收到这个错误:

Error Code: 1005. Can't create table 'adstudio.data_feed_param' (errno: -1)

之前,我尝试用许多其他列创建此 table,其中一列名为 input_type,并且我有一个与 input_type 有外键关系的列:

CREATE TABLE IF NOT EXISTS `adstudio`.`data_feed_param` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  ...
  `input_type` TINYINT UNSIGNED NOT NULL DEFAULT '1',
  ...
  PRIMARY KEY (`id`),
  INDEX `fk_input_type_idx` (`input_type` ASC),
  CONSTRAINT `fk_input_type`
    FOREIGN KEY (`input_type`)
    REFERENCES `adstudio`.`input_type` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

我注意到当 Propel 无法重新生成时,此列很糟糕。我删除了 table,更改了列名,现在我无法添加与 InnoDB 引擎名称完全相同的 table。

但是,我能够在 MyISAM 中创建一个具有完全相同名称的 table,插入和删除它都没有问题。

如何修复数据库以便创建 table?

2015 年 6 月 1 日更新:所以除了在不同的情况下,我又失去了相同的 table 。首先,我在 table 名称中添加了前缀以避免上述问题,adstudio.account_data_feed_param.

其次,我正在对此 table 进行更改而不是删除它。我运行一个ALTER添加了一个栏目,但是收到了消息"The MySQL Server has gone away"。我在 MySQL Workbench.

中完成了所有这些

第三,我有一个多对多 table 引用了这个 ,其中填充了数据 。这怎么可能? MySQL 怎么会随意丢弃我的 table?

如果我尝试访问外键定义,我会收到以下消息:

Error getting DDL for object.
Table 'adstudio.account_data_feed_param' doesn't exist

这是 SQL 现在 table 的创作:

-- -----------------------------------------------------
-- Table `adstudio`.`account_data_feed_param`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `adstudio`.`account_data_feed_param` (
  `id` BIGINT(20) UNSIGNED NOT NULL,
  `account_id` BIGINT(20) UNSIGNED NOT NULL,
  `name` VARCHAR(64) NOT NULL,
  `default_value` VARCHAR(64) NOT NULL,
  `input_type_id` SMALLINT(5) UNSIGNED NOT NULL,
  `lookups_json` MEDIUMTEXT NOT NULL,
  `enabled` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
  `creation_user_id` BIGINT(20) UNSIGNED NOT NULL,
  `creation_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `last_modified_user_id` BIGINT(20) UNSIGNED NOT NULL,
  `last_modified_date` TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:01',
  `deletion_user_id` BIGINT(20) UNSIGNED NULL DEFAULT NULL,
  `deletion_date` TIMESTAMP NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  INDEX `dfp_account_idx` (`account_id` ASC),
  INDEX `dfp_input_type_idx` (`input_type_id` ASC),
  INDEX `dfp_creation_user_idx` (`creation_user_id` ASC),
  INDEX `dfp_last_modified_user_idx` (`last_modified_user_id` ASC),
  INDEX `dfp_deletion_date_idx` (`deletion_user_id` ASC),
  CONSTRAINT `dfp_account`
    FOREIGN KEY (`account_id`)
    REFERENCES `adstudio`.`account` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `dfp_input_type`
    FOREIGN KEY (`input_type_id`)
    REFERENCES `adstudio`.`input_type` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `dfp_creation_user`
    FOREIGN KEY (`creation_user_id`)
    REFERENCES `adstudio`.`user` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `dfp_last_modified_user`
    FOREIGN KEY (`last_modified_user_id`)
    REFERENCES `adstudio`.`user` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `dfp_deletion_date`
    FOREIGN KEY (`deletion_user_id`)
    REFERENCES `adstudio`.`user` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARACTER SET = utf8;

这是我试过的 ALTER 语句 运行ning:

ALTER TABLE `adstudio`.`account_data_feed_param` 
    ADD COLUMN `input_type` VARCHAR(32) NOT NULL DEFAULT 'text' AFTER `input_type_id`;

并尝试在纯 MySQL 命令行界面中创建相同的 table,我现在收到:

ERROR 1005 (HY000): Can't create table 'adstudio.account_data_feed_param' (errno: -1)

我假设 InnoDB

我的数据库 运行 脱离 Amazon RDS,所以我只有他们提供给我的访问权限。这是我 运行 正在使用的服务器版本:

mysql> SELECT VERSION();
+------------+
| VERSION()  |
+------------+
| 5.5.40-log |
+------------+
1 row in set (0.02 sec)

我真的,真的不想重构我所有的代码,因为 MySQL 不允许我重新创建我的 table。那太蠢了。与此同时,我提出这个问题以寻求赏金。

文档说:

Error 1005 (ER_CANT_CREATE_TABLE)

If the error message refers to error –1, table creation probably failed because the table includes a column name that matched the name of an internal InnoDB table.

首先在这个 table 上尝试 DROP TABLE,然后尝试重新添加它

如果您的方案是正确的,请检查 mysql/data/{您的数据库名称} 中的目录以查找具有您的 table 名称的文件。删除任何(移动它们以防万一您需要它们来进一步解决问题)。 之后创建带有名称和单列的 table 以检查是否解决了问题。

InnoDB 中的 DDL 不是事务性的,因此 .frm 文件和 InnoDB 字典中的信息可能不同。在你的情况下,看起来 .frm 文件丢失了,但字典中有一个孤立的记录(好吧,实际上记录在几个字典 SYS_* 表中)。

您不能轻易地从字典中删除记录。您需要一个相应的 .frm 文件,以便 MySQL 将您的 DROP 传递到 InnoDB 级别。使用 RDS,您无法做到这一点。

但是您可以删除整个数据库。在这种情况下,InnoDB 将从字典中删除所有记录,包括孤立记录。

所以,为了清理你的字典,我建议如下:

  1. 停止到 MySQL 的所有流量,将其设为只读
  2. 创建临时数据库adstudio_tmp
  3. RENAMEadstudioadstudio_tmp
  4. 的所有表格
  5. DROP DATABASE adstudio。此时它是空的。 DROP 将清除 InnoDB 字典中的所有条目。
  6. RENAME 所有表格从 adstudio_tmp 返回到 adstudio

在此之后字典应该是干净的,您将能够创建您的data_feed_param

我在 unsuccessful ALTER TABLE 之后描述了类似的问题。查看更多详情。

从 5.5 升级到 5.6 后,我在尝试创建完全相同的表时收到新错误:

Error Code: 1813. Tablespace for table '`adstudio`.`account_data_feed_param`' exists. Please DISCARD the tablespace before IMPORT.

我假设声明:

DROP TABLESPACE `data_feed_param`;

现在无需 RENAME 我的表即可解决我的问题,但遗憾的是我们无法获得数据库用户的 CREATE TABLESPACE 权限。