mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)

概述

我们很多时候都会去drop一些大表,特别是生产环境做操作时,这里主要提一些注意事项,仅供参考。


01相关语法

1、删表

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语句会隐式提交),不会进行权限检查。

2、删库

DROP DATABASE Syntax DROP {DATABASE | SCHEMA} [IF EXISTS] db_name...

删除指定库中的表之后删除库。需具有库上的DROP权限。库被删除后库上存在的用户权限不会被自动删除。IF EXISTS用于阻止库名不存在时引起的错误。库被删除后默认库会被重置。若在使用了符号链接的库上执行DROP DATABASSE 连接和原始数据库都会被删除。命令返回被移除的表数量。

使用InnoDB引擎且指定innodb_file_per_table=ON时在数据目录中与该表对应的有如下两个文件,分别为表定义文件和数据文件。

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(1)

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(2)

2、drop table

直接使用DROP TABLE来完成删表动作,正常这条语句要执行很长时间。因为数据量只有5G,所以不是很明显。(这台服务器空间不够了,所以数据量没加上去..)

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(3)

3、建立硬链接

此时便可以通过在该表对应的数据文件上设置硬链接来进行删除。

#ln /data/datafile/test/no_part_tab.MYD /data/datafile/test/no_part_tab.MYD.hdlk #ls -lh /data/datafile/test/

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(4)

发现多了一个sys_user.ibd.hdlk文件,且no_part_tab.MYD.hdlk和no_part_tab.MYD的innode均为2。也即当有多个文件名(如硬链接)指向同一innode时,这个innode的引用数大于1,此时,删除其中任何一个文件名都只会删除指向innode的指针而并不会直接删除物理文件块,因此会非常快,直至innode的引用计数等于1时才会真正删除对应的物理文件块,真正删除物理文件块时才会比较耗时。

4、drop table

在建立了硬链接后再执行DROP TABLE操作:

DROP TABLE no_part_tab;

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(5)

可以看到基本没耗时,查看对应的表定义和数据文件:

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(6)

只剩下no_part_tab.MYD.hdlk,且innode的引用计数变为了1。也即刚才的DROP TABLE操作实施删除了物理文件的一个指针no_part_tab,因而非常快。

5、删除真正的物理文件

因为此时innode的引用计数已经变为了1,直接删除no_part_tab.MYD.hdlk便会真正的删除物理文件。但因为物理文件较大,删除大文件仍会引起较高的磁盘IO开销。因此可以使用少量逐次删除的方式来删除大的数据文件。truncate工具可以用于增加或缩减指定文件的尺寸,可以用于此目的:

#for i in `seq 6 -1 1 ` ;do sleep 2;sudo truncate -s ${i}G /data/datafile/test/no_part_tab.MYD.hdlk;done #rm -rf /data/datafile/test/no_part_tab.MYD.hdlk;

从6G开始,每次缩减1G,停2秒,继续,直到文件只剩1G,最后使用rm命令删除剩余的部分。

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(7)

如果是整个数据库的删除可以先删除其中较大的表,最后在执行DROP DATABASE删除整个库,对大表的删除可参见上面的方法。


后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下!

mysql大表清理数据(详解mysql生产环境如何快速有效的删除大表)(8)

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页