语法:
删表
DROP TABLE Syntax DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCADE]
登录后复制
可一次删除一张或多张表。需具有所删除表上的DROP权限。表定义文件和数据文件均被移除。表被删除后表上的用户权限不会被自动删除。参数里表中指定的表名不存在则报错,但对于存在的表仍会删除。可通过指定IF EXISTS阻止表不存在时引发的错误(此时对于不存在的表仅产生一个NOTE)。对于分区表,除了移除表定义,分区、数据外还移除与之关联的分区定义文件(.par)。在MySQL5.6中参数[RESTRICT | CASCADE]不做任何事情。[TEMPORARY] 关键字表明只删临时表,语句不会结束正在进行的事务(MySQL中DDL语句会隐式提交),不会进行权限检查。
删库DROP DATABASE Syntax DROP {DATABASE | SCHEMA} [IF EXISTS] db_name...
登录后复制
该命令会从指定的数据库目录中移除常规操作时MySQL自己产生的文件和目录,如:.BAK .DAT .HSH .MRG. MYD .MYI .TRG .TRN .db.frm .ibd .ndb .par,若存在db.opt也同样会删除。若数据库目录中存在其他非MySQL本身产生的文件或目录,则整个数据库目录不会被移除。此时,需手动清理剩余的文件并重新运行DROP DATABASE语句。
删除数据库并不会移除库中创建的临时表。临时表在SESSION结束时自动被清理或者显示的通过DROP TEMPORARY TABLE 删除。
删除大表的注意事项
对于表的删除,因为InnoDB引擎会在table cache层面维护一个全局独占锁一直到DROP TABLE完成为止,这样,对于表的其他操作会被HANG住。对于较大的表来说,DROP TABLE操作可能需要很长的时间,因此需要一种有效的办法来提升大表的删除速度,以尽可能降低HANG住的时间。可以通过设置硬链接来达到此目的。
比如有一个样例表:
example_table
使用InnoDB引擎且指定innodb_file_per_table=ON时在数据目录中与该表对应的有如下两个文件,分别为表定义文件和数据文件。
sudo ls -lh /data/mysql/testdb -rw-rw---- 1 mysql mysql 8.4K Oct 28 13:26 example_table.frm -rw-rw---- 1 mysql mysql 100G Oct 28 13:26 example_table.ibd
登录后复制
sudo ln /data/mysql/testdb/example_table.ibd /data/mysql/testdb/example_table.ibd.hdlk sudo ls -lh /data/mysql/testdb -rw-rw---- 1 mysql mysql 8.4K Oct 28 13:26 example_table.frm -rw-rw---- 2 mysql mysql 100G Oct 28 13:26 example_table.ibd -rw-rw---- 2 mysql mysql 100G Oct 28 13:26 example_table.ibd.hdlk
登录后复制
在建立了硬链接后再执行DROP TABLE操作:
DROP TABLE example_table;
登录后复制
sudo ls -lh /data/mysql/testdb -rw-rw---- 1 mysql mysql 100G Oct 28 13:26 example_table.ibd.hdlk
登录后复制
剩下的任务就是删除真正的物理文件了,因为此时innode的引用计数已经变为了1,直接删除example_table.ibd.hdlk便会真正的删除物理文件。但因为物理文件较大,删除大文件仍会引起较高的磁盘IO开销。因此可以使用少量逐次删除的方式来删除大的数据文件。truncate工具可以用于增加或缩减指定文件的尺寸,可以用于此目的:
for i in `seq 100 -1 1 ` ;do sleep 2;sudo truncate -s ${i}G /data/mysql/testdb/example_table.ibd.hdlk;done sudo rm -rf /data/mysql/testdb/example_table.ibd.hdlk;
登录后复制
对于整个数据库的删除可以先删除其中较大的表,最后在执行DROP DATABASE删除整个库,对大表的删除可参见上面的方法。