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,阻碍任何DROP
或ALTER
:(
似乎 MySQL 的重新启动允许它识别新的数据库和表更改并更新与我想要更改的 InnoDB
数据库表和表空间相关联的某种 SDI (Serialized Dictionary Information) 元数据。不知何故,这种对 SDI 信息的识别阻碍了我的 ALTER
和 DROP
命令。 这可能是 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)
在我的例子中,表引擎是InnoDB
和MyISAM
的混合体。它们应该都是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
ALTER TABLE DROP COLUMN 失败,因为一个或多个对象访问此列