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


46

新的CentOS安装。

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

所以我尝试了

DROP DATABASE huge_db;

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

/etc/init.d/mysqld restart

DROP DB窗口消息:服务器关闭。然后,我实际上重新启动了物理服务器。

重新登录到mysql,检查并且db仍然存在,运行

DROP DATABASE huge_db;

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

再一次,它是全新的安装。的huge_db是唯一的分贝(除系统DBS其他)。我发誓我已经并且很快就放弃了这么大的数据库,但是也许我错了。

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

删除数据库最终花费了30分钟,因此,再次,我可能不必重新启动服务器,并且可能刚刚等待DROP完成,但是我不知道mysql如何响应获取DROP查询。通过mysqldump导入的同一个数据库。

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

Answers:


73

如果您在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 |
+-----+------+-----------+-------------------+---------+------+-------+------------------+

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

$ mysqladmin kill 174

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

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

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

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


1
@BugsBuggy发生这种情况的一种常见方式是,如果另一个进程(例如Web服务器,或者在这种情况下是导入进程)正在运行并连接到数据库。发出DROP DATABASE命令时,直到所有连接都关闭,服务器才能继续。
Stefan Magnuson

11

尽管我认为导入过程已经死了,但它可能仍在运行。

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

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

如果其他任何人都读了此文件并试图取消数据库导入并删除数据库,我建议您首先找到导入的PID(进程ID),然后从另一个终端运行它:

$ kill [PID]

...其中[PID]是该过程的实际PID。

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

您也可以SHOW PROCESSLIST在phpMyAdmin SQL选项卡中运行。结果表显示了正在运行的进程,单击要杀死的行旁边的“ x”即可解决问题。

然后跑

DROP DATABASE `database_name`;

一切都应该干净。


另一个答案表明,杀死mysql内部的进程比从外部执行更好。我尚未测试该答案,但听起来很合理。因此,我将其标记为“可接受的答案”,而不是此答案。




3

我遇到了同样的问题。但是这次我查看了show processlist。它说检查权限更长的时间。然后我发现mysqld_safe以root身份运行,而文件夹级权限仅适用于mysql用户。因此,我杀死了该查询,当然要花很长时间说它处于被杀死状态,但是我等待它做出反应,然后它杀死了该查询,并且还通过将其添加到group并将chmod设置为770来将文件夹级别的权限更改为root。同样的drop数据库等等;对于20GB数据库,它确实在2秒内为我工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.