为什么 DROP DATABASE 需要这么长时间?(MySQL)

But*_*kus 55 mysql mysqldump

新的 CentOS 安装。

我正在运行一个大型数据库(2GB sql 文件)的导入并且遇到了问题。SSH 客户端似乎失去了连接,导入似乎冻结了。我使用另一个窗口登录到 mysql 并且导入似乎已死,卡在特定的 3M 行表上。

所以我试过了

DROP DATABASE huge_db;
Run Code Online (Sandbox Code Playgroud)

15-20分钟后,什么都没有。在另一个窗口中,我做了:

/etc/init.d/mysqld restart
Run Code Online (Sandbox Code Playgroud)

DROP DB 窗口显示消息:SERVER SHUTDOWN。然后我实际上重新启动了物理服务器。

重新登录到 mysql,检查并且数据库还在那里,然后运行

DROP DATABASE huge_db;
Run Code Online (Sandbox Code Playgroud)

再一次,我已经等了大约 5 分钟。

再次,这是全新安装。这huge_db是唯一的数据库(系统数据库除外)。我发誓我之前和很快就放弃了这么大的 db,但也许我错了。

我已经成功删除了数据库。大约花了 30 分钟。另请注意,当我认为 mysqldump 导入已死时,我认为我错了。终端连接丢失,但我认为该过程仍在运行。我很可能杀死了导入中间表(3M 行表),并且可能杀死了整个数据库的 3/4。“top”显示 mysql 只使用了 3% 的内存,而看起来它应该使用更多内存,这是一种误导。

删除数据库最终需要 30 分钟,因此,我可能不必重新启动服务器,也可能只是等待 DROP 完成,但我不知道 mysql 会如何对获取 DROP 查询做出反应它通过 mysqldump 导入的同一个数据库。

尽管如此,问题仍然存在,为什么在删除所有 db 文件并从 information_schema 中删除对 DB 的所有引用时,DROP 2GB 数据库需要 30 分钟以上?有什么大不了的?

Ste*_*son 88

与其杀死进程,不如在 MySQL 中执行它会更安全:

$ mysqladmin processlist -u root -p
Enter password: 
+-----+------+-----------+-------------------+---------+------+-------+------------------+
| Id  | User | Host      | db                | Command | Time | State | Info             |
+-----+------+-----------+-------------------+---------+------+-------+------------------+
| 174 | root | localhost | example           | Sleep   | 297  |       |                  |
| 407 | root | localhost |                   | Query   | 0    |       | show processlist |
+-----+------+-----------+-------------------+---------+------+-------+------------------+
Run Code Online (Sandbox Code Playgroud)

id 为 174 的查询是一个阻止删除“示例”数据库的查询,因此在您终止任何进程之前,首先让 MySQL 尝试终止查询:

$ mysqladmin kill 174
Run Code Online (Sandbox Code Playgroud)

processlist再次运行上面的命令以确认它已被杀死。

如果这不起作用,那么您也许可以考虑终止错误的进程,但在此之前您可以尝试重新启动 MySQL 服务器。

您还可以在 MySQL shell 中运行诸如“SHOW FULL PROCESSLIST”和“KILL 174”之类的命令,例如,如果您只安装了 MySQL 客户端。重点是避免在 shell 中使用“kill”来终止进程,除非绝对必要。

一般来说,您可以使用mysqlmysqladmin。不过,您不应该经常运行这样的命令;一旦您开始定期终止查询,肯定会出现问题,您最好解决该问题(终止查询过程只是治疗症状)。

  • @BugsBuggy 发生这种情况的一种常见方式是,如果另一个进程(例如 Web 服务器,或在这种情况下是导入进程)正在运行并连接到数据库。当您发出“DROP DATABASE”命令时,在所有连接都关闭之前,服务器不会继续运行。 (2认同)

But*_*kus 11

虽然我认为导入过程已经死亡,但它可能仍在运行。

DROP DATABASE命令可能在运行之前等待数据库完成导入。

因此,与其DROP DATABASE花费很长时间,不如说只是导入。

1.)

如果其他人读到这个并试图取消数据库导入并删除数据库,我建议您首先找到导入的 PID(进程 ID)并从不同的终端运行它:

$ kill [PID]
Run Code Online (Sandbox Code Playgroud)

...其中 [PID] 将是进程的实际 PID。

如果另一个终端仍然连接,您应该立即看到导入停止。

2.)

您还可以SHOW PROCESSLIST在 phpMyAdmin SQL 选项卡中运行。结果表显示正在运行的进程,单击要杀死的行旁边的“x”应该可以解决问题。这与接受的答案或从命令行终止mysql进程的效果相同mysql

然后运行

DROP DATABASE `database_name`;
Run Code Online (Sandbox Code Playgroud)

一切都应该是干净的。


另一个答案表明,在 mysql 中终止进程比从外部执行要好。我还没有测试过这个答案,但这听起来很有道理。所以我把它标记为“接受的答案”而不是这个。