MySQL怎样快速的 drop 掉一个 100G 的大表?
别看 drop 命令很简朴,但是当实行机遇不对,实行姿势不对,大概会引发“大祸”。
那么,drop 一张表的时候,MySQL 的底层都干了些什么?
它为什么会慢,怎样快速的举行一张表的 drop?
从高性能 MySQL 一书中,我们得出,MySQL 的 drop 命令,告急干了两件事:
清除 Buffer Pool 缓冲
删除对应的磁盘数据文件 ibd
针对第一点,当我们的 Buffer Pool 缓冲设置的越大,drop 时就越耗时,因此公道的 Buffer Pool 缓冲区设置就显得很告急。
第二点,尤其告急,由于它是真正存数据的文件。drop 数据慢,最大的缘故原由,就是和它有关。
在DROP TABLE的时候,全部进程不管是DDL照旧DML都被HANG起,直到DROP竣事才继承实行。
这是由于INNODB会维护一个全局独占锁(在table cache上面),直到DROP TABLE完成才释放。
在我们常用的ext3,ext4,ntfs文件体系,要删除一个大文件(几十G,以致几百G)照旧须要点时间的。
在我们删除物理数据文件时,假如数据文件过大,删除过程会产生大量的 IO 并淹灭更多的时间,造成磁盘 IO 开销飙升,CPU 负载过高,影响其他步调运行。
幸亏 Linux 提供的有硬毗连特性,我们可以公道的使用这个特性,加快删除速率。
当多个文件名同时指向同一个 INODE 时,这个 INODE 的引用数 N > 1,删除此中任何一个文件名都会很快。由于其直接的物理文件块没有被删除,只是删除了一个指针而已;当 INODE 的引用数 N = 1 时,删除文件须要去把这个文件相干的全部数据块清除,以是会比力耗时。
三、操纵
查察个表巨细,用MB展示:
select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)'from information_schema.tablesorder by data_length desc, index_length desc;因此,我们可以公道的使用这个机制,给数据库表的 .ibd 文件创建一个新的硬链接。
假如是主从架构,请在全部呆板上创建硬链接。
当删除表时,删除物理文件时,实在删除的就是物理文件的一个指针,以是删除操纵相应速率会非常快,不到 1 秒就能完成这个操纵。
末了就是要真正删撤消物理文件,释放文件所占用的磁盘空间。这一步我就不睁开说了,网上有很多工具,都可以做到。
直接从硬盘文件中删除:
$ rm -f table_test.ibd.bak分步删除,末了从硬盘中删除文件
100 G 文件,每删除1G内容歇1秒,直到末了文件只剩下1G,删除文件
$ for i in `seq 100 -1 1 ` ; do sleep 1; truncate -s ${i}G table_test.ibd.bak; done $ rm -f table_test.ibd.bak我们这里讲了大表的 drop,同样的,这个过程这恰当大库 drop。假如一个数据库比力大,那我们可以先删除此中较大的表,末了在实行 DROP DATABASE 删除整个库,对大表的删除可拜见上面的方法。
假如要重修表,那么可以在删除表之前,先备份建表语句。