MySQL 8 - DROP 或 ALTER 导致错误 3664 (HY000): 无法设置 SDI

Posted

技术标签:

【中文标题】MySQL 8 - DROP 或 ALTER 导致错误 3664 (HY000): 无法设置 SDI【英文标题】:MySQL 8 - DROP or ALTER Causes ERROR 3664 (HY000): Failed to set SDI 【发布时间】:2018-10-30 14:27:48 【问题描述】:
ERROR 3664 (HY000): Failed to set SDI 'MyDatabase.MyTable' in tablespace 'mydatabase/mytable'.

每当尝试DROP 数据库或ALTER 表时,我都会遇到此错误。我无法删除或更改我创建的任何表格。

现在,真正有趣的是这些错误仅在重新启动 MySQL 并随后(由 root 用户)登录到 MySQL 后发生。这是模式:

    以 root 用户身份登录 mysql。 创建数据库并创建表。 DROP 数据库或ALTER 没有问题的表:) 退出 MySQL 重新启动 MySQL(停止然后启动) 以 root 用户身份登录 MySQL。 尝试DROP 数据库或ALTER 我之前创建的表时出现错误3664,阻碍任何DROPALTER :(

似乎 MySQL 的重新启动允许它识别新的数据库和表更改并更新与我想要更改的 InnoDB 数据库表和表空间相关联的某种 SDI (Serialized Dictionary Information) 元数据。不知何故,这种对 SDI 信息的识别阻碍了我的 ALTERDROP 命令。 这可能是 MySQL 中的错误吗?或者,我的 root 用户是否无权运行修改 SDI 数据的命令? (尽管文档说 SDI 数据是由内部 API 修改的。)

每次创建数据库和表时都会发生这种情况。所以,我对这个错误非常严重的解决方法

    手动删除数据目录下与数据库关联的数据文件。 调用DROP DATABASE IF EXISTS MyDatabase;(可能需要注销/登录几次,或重新启动 MySQL 并尝试使用SELECT 语句访问表才能最终工作) 重新创建所需的数据库和表。

任何帮助将不胜感激!谢谢!


我在 Mac 上运行 MySQL 8.0.11 社区服务器。

同样的问题没有解决方案:Unable to drop database mysql: ERROR 3664 (HY000)

【问题讨论】:

老实说,这似乎不是编程问题。要么有一些配置设置需要设置,要么是一个错误。 DBA SE 站点会更好地提出这个问题,因为 DBA 比程序员更了解配置设置和错误。 @Shadow 我已将此帖子添加到 MySQL 论坛,如果它获得论坛批准,我将发布链接。谢谢! @TimArterbury 你找到解决这个问题的方法了吗? @eveevans 遗憾的是没有。我在 MySQL 论坛上发帖,但似乎我的帖子从未获得批准。我可能会尝试提交错误报告。有趣的是这样一个简单的错误并没有被捕获。我只是想使用一个基本的 MySQL 功能来删除数据库 lolz。 我认为这是错误。删除数据库的单一方法是删除文件,然后重复删除模式。 【参考方案1】:

这是mysql-8.0.11中的一个相关补丁:

https://github.com/mysql/mysql-server/commit/261981bdf42c110f08f98ad2cf84ce6fdef1949e

sdi_debug.result 似乎表明

SET GLOBAL DEBUG = '-d, sdi_delete_failure';

需要解决这个问题。

【讨论】:

有趣。当我运行命令SET GLOBAL DEBUG = '-d, sdi_delete_failure'; 时,我得到ERROR 1193 (HY000): Unknown system variable 'DEBUG' @Xypron 不,这只是在运行测试套件(在调试版本上)时清除用于触发错误模拟的标志。请注意测试如何通过+d(设置)和-d(清除)的两次迭代。【参考方案2】:

如果您清空所有表,则可以删除架构。

有趣的是,如果在 php 中使用 PDO,则此语句有效

$conn->exec("DROP DATABASE IF EXISTS $dbname");

【讨论】:

【参考方案3】:

问题与外键有关。此语句失败:

CREATE TABLE `lottery` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `club_id` int(11) unsigned DEFAULT NULL,
  `title` varchar(255) DEFAULT NULL,
  `details` text,
  `open_date` date DEFAULT NULL,
  `close_date` date DEFAULT NULL,
  `status_id` smallint(6) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `fk_lottery_club` (`club_id`),
  CONSTRAINT `fk_lottery_club` FOREIGN KEY (`club_id`) REFERENCES `club` (`id`) ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

但如果我删除 KEY 和 CONSTRAINT 子句,它就可以工作。

CREATE TABLE `lottery` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `club_id` int(11) unsigned DEFAULT NULL,
  `title` varchar(255) DEFAULT NULL,
  `details` text,
  `open_date` date DEFAULT NULL,
  `close_date` date DEFAULT NULL,
  `status_id` smallint(6) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建之后,我必须使用 ALTER TABLE 重新添加这些键。

至少可以说很烦人。

【讨论】:

我了解您在删除特定表格时提出的问题是由于关键限制。但是,我的问题是删除(DROPing)数据库。我遇到了某种表空间问题,而不是外键问题。对于您提供的代码,删除整个数据库时不应出现外键约束错误。 我没有收到外键错误。我遇到了与删除整个数据库时相同的 SDI 错误。【参考方案4】:

FWIW,我在尝试时遇到了同样的“无法设置 SDI”错误:

ALTER TABLE 'MyDb.MyTable' ADD COLUMN 'myCol' VARCHAR(255)

在我的例子中,表引擎是InnoDBMyISAM 的混合体。它们应该都是InnoDB,当我切换它们并重新启动 MySQL 服务器时,一切似乎都正常了。

MySql 的数据目录中有各种.sdi 文件(我的机器上的/usr/local/mysql/data/MyDb/)...这只是一个简单的json 文件,其中包含与特定表相关的元数据。这些 SDI 文件似乎只存在于 MyISAM 表中。

在我意识到这一点之前,我认为特定表的 SDI 文件一定是丢失了,或者其他什么,结果 mysql 在其 bin 目录中有一个 ibd2sdi 实用程序可以创建来自表ibd 文件(也在数据目录中)的 SDI 文件。

如果您需要坚持使用MyISAM,可能值得一看。不过要小心修改 SDI 文件的内容,因为我遇到了this quote in the MySql worklogs:

执行此操作时必须非常小心 - 与 .MYD 和 .MYI 文件中存储的内容不兼容的更改(例如更改列的数据类型)可能是灾难性的,必须避免。

不知道这是否有帮助,但我想我会分享。

【讨论】:

【参考方案5】:

我和我的几个学生发现这个问题越来越多。

作为一种解决方法,我发现如果您进入并在问题数据库中的所有表上执行analyze table,它将修复此错误,直到您下次重新启动服务器。

【讨论】:

嗨。我们也有这个 SDI 问题。我可以知道您使用的是什么操作系统吗? 我在 Mac 上使用 High Sierra。

以上是关于MySQL 8 - DROP 或 ALTER 导致错误 3664 (HY000): 无法设置 SDI的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 11g XE "alter table drop column" 导致 ORA-00600

mysql对字段的操作

MySql之ALTER命令用法详细解读(转)

ALTER TABLE DROP COLUMN 失败,因为一个或多个对象访问此列

MVC - ALTER TABLE DROP COLUMN 失败,因为一个或多个对象访问此列

mysql索引