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

Nob*_*ift 5 mysql innodb errno amazon-web-services amazon-rds

提示:千万不能运行ALTER在MySQL Workbench中陈述的"标准TCP/IP通过SSH"连接.shell进入服务器并ALTER从那里运行更好.这样,如果你失去了与服务器的连接,那么ALTER应该仍然完成它的工作.

我正在尝试在我昨天尝试创建的数据库中创建一个新表.问题是,我的互联网一直在失去微辍学的联系.我相信当我创建表时发生了其中一个blips,现在当我尝试创建一个具有完全相同名称的表时:

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;
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

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

以前,我尝试使用许多其他列创建此表,其中一列已命名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;
Run Code Online (Sandbox Code Playgroud)

我注意到当Propel无法再生时,这个专栏很糟糕.我删除了表,更改了列名,现在我无法添加与InnoDB引擎完全相同名称的表.

但是,我能够在MyISAM中创建一个具有完全相同名称的表,插入并放弃它而不会出现问题.

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

更新2015/06/01:除非在不同的情况下,我再次丢失了同一张桌子.首先,我在表名中添加了一个前缀以避免上述问题adstudio.account_data_feed_param.

其次,我正在对此表进行更改而不是删除它.我跑了一个ALTER添加列,但收到消息"MySQL服务器已经消失".我在MySQL Workbench中完成了所有这些工作.

第三,我有一个多对多表,引用了这个表,其中填充了数据.这怎么可能呢?MySQL如何随意丢弃我的表?

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

Error getting DDL for object.
Table 'adstudio.account_data_feed_param' doesn't exist
Run Code Online (Sandbox Code Playgroud)

这是表的创建SQL:

-- -----------------------------------------------------
-- 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;
Run Code Online (Sandbox Code Playgroud)

这是ALTER我试过的声明:

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

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

ERROR 1005 (HY000): Can't create table 'adstudio.account_data_feed_param' (errno: -1)
Run Code Online (Sandbox Code Playgroud)

我假设InnoDB

我的数据库正在运行Amazon RDS,因此我只能访问他们提供的访问权限.这是我正在运行的服务器版本:

mysql> SELECT VERSION();
+------------+
| VERSION()  |
+------------+
| 5.5.40-log |
+------------+
1 row in set (0.02 sec)
Run Code Online (Sandbox Code Playgroud)

我真的,真的不想重构我的所有代码,因为MySQL不允许我重新创建我的表.那只是愚蠢的.与此同时,我正在提出这个问题以获得赏金.

aku*_*sky 5

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

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

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

所以,为了清理你的字典,我建议遵循:

  1. 停止对MySQL的所有流量,使其成为只读
  2. 创建一个临时数据库 adstudio_tmp
  3. RENAME从所有表adstudioadstudio_tmp
  4. DROP DATABASE adstudio.此时它是空的.该DROP会消灭在InnoDB的字典中所有条目.
  5. RENAME所有表从后adstudio_tmpadstudio

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

我在ALTER TABLE失败后描述了类似的问题.查看更多详细信息.