MySQL的“drop database”为什么需要时间?

11

mysql5.0带有一对数据库"A"和"B",两者都有大型的innodb表格。执行"drop database A;"会导致数据库"B"冻结几分钟。此时没有任何程序在使用"A",为什么这个操作如此耗费资源?

额外提示:如果我们需要使用"A",将数据上传到"B",然后切换到使用"B",如何更快地完成此操作?通常情况下,删除数据库不是一个经常需要做的事情,因此这有点超出了正常范围。


我曾经遇到过类似的问题,但其他数据库都是正常的。解决方法是杀掉所有使用该数据库的其他进程,因为它们正在锁定它(可能是通过选择该数据库隐式地进行锁定,因为它们正在睡眠)。 - GDR
3个回答

13

所以我不确定Matt Rogish的答案是否会百分之百地有帮助。

问题在于MySQL*在打开和关闭表时有一个互斥锁(mutually exclusive lock),这基本上意味着如果一个表正在关闭/删除过程中,没有其他表可以被打开。

我的一位同事在这里描述了这个问题:http://www.mysqlperformanceblog.com/2009/06/16/slow-drop-table/

一个很好的减少影响的策略是使用像XFS这样的文件系统。

解决方法很丑陋。您必须在删除表之前逐渐地删除表中的所有数据(请参见上面链接中的评论#11)。


所以你已经解释了锁定机制,一切都很清楚...但是“为什么”仍然没有得到回答。在Linux中删除一堆文件并不需要很长时间。因此,我猜在幕后发生了更复杂的事情。如果是这样,那么“为什么”要这样做,而不是在几秒钟内简单地删除其文件,然后“哔哩哔哩”...所有表都被删除? - Jeach
1
除了文件系统缓慢删除之外,还有另一个原因 - 如果存在非常大的缓冲池,则在尝试驱逐属于即将删除的表的所有页面时可能会出现冻结。这在5.5 / 5.6中通过“惰性”释放方法得到改进。 - Morgan Tocker
以上链接已经失效,重定向到其他网站。 - KrishPrabakar

10

继续阅读skaffman的内容:

修改你的my.cnf文件(并重新启动MySQL),加入以下内容:

innodb_file_per_table = 1

(http://mysqldba.blogspot.com/2006/12/innodbfilepertable.html)

这将为您的数据库提供专用文件存储,并将其从共享池中取出。然后,您可以做一些有趣的事情,例如将表/索引放置在不同的物理磁盘上,以进一步分割I / O并提高性能。
请注意,这不会更改现有的表格;你需要努力让它们拥有自己的文件(http://capttofu.livejournal.com/11791.html)。

1
我认为你夸大了使用innodb_file_per_table = 1来分割I/O的用处 - RAID是更好的选择。原因:InnoDB不支持称为DATA DIRECTORY的CREATE TABLE选项。如果我想将单个表移动到另一个分区,我必须使用符号链接返回到原始位置。一旦运行ALTER TABLE命令,符号链接就会被破坏,表就会移回原始位置。 - Morgan Tocker
我很惊讶这个单一选项会带来如此巨大的影响。你真是救命恩人! - Milan Simek

6
默认情况下,同一台mysql服务器安装中的所有innodb数据库使用相同的物理数据文件池,因此“drop database A”可能会影响数据库B。由于“drop database”可能涉及对innodb数据文件的大量重组,因此这可能是一个阻塞操作,要么是由于操作强度,要么是由于设计。
然而,我认为您可以使每个数据库使用不同的物理文件,尽管我自己没有尝试过,因此您需要自行确定具体细节。如果失败,那么您可能需要在同一台机器上并排使用两个不同的mysql安装程序,这是完全可行的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接