众所周知drop table会严重的消耗服务器IO性能,如果被drop的table容量较大,甚至会影响到线上的正常。
首先,我们看一下为什么drop容量大的table会影响线上服务
直接执行drop table,mysql会将表定义和表数据全都删除,包括磁盘上的物理文件,也包括buffer pool中的内存数据。
这就分两步,第一步从buffer pool中删除,这会涉及到table_cache的lock,如果持有table_cache的lock,这将导致其他查询都无法执行。这种情况在没有innodb_per_table之前尤为严重。另外,mysql5.5.23之后添加lazy drop table功能,这个功能用来解决mutex on the LRU list。其中心思想就是加锁,找到需要被删除的page,删除1024个page之后释放锁让其他thread工作,之后loop。而percona的lazy drop处理起来更优雅一些,其会先加锁,然后找到需要被删除的page,标记,释放锁,后台慢慢删除。
之后就是第二步,这步在大容量表的时候更为消耗时间,那就是在os上删除物理文件。大家都知道在ext3上rm一个200G的文件会非常耗时,这是由于ext3存储数据的结构导致,如果一个很大的文件,ext3的i_block无法直接存放,需要多层嵌套才能完全存储下,在这种情况下由于映射的层次多,并且由于多层映射也不会是顺序存储的,就导致了很大的随机IO,这就导致了删除物理文件非常慢的现象。在这种情况下,建议升级到ext4,这是由于ext4比ext3使用extent分配存储空间,其最大的优势就是顺序存储。
ext3:
ext4:
知道了原因,我们来说说如何解决。具体步骤如下:
1、建立硬链接。
ln table.ibd table.idb.hdlk
2、mysql执行drop table操作。
drop table if exists tablename;
3、使用truncate删除物理文件。
truncate -s 1024*1024*4 filename
其实硬链接和drop table就不用多说了,在建立硬链接之后,mysql会认为rm了硬链接文件之后就算操作完毕,不会真正去删除物理文件从而提高了速度。但是对于服务器来说,实际的物理文件还在,如果手动rm,还是会产生很多的io影响,这时候就用到了truncate这个工具。这个工具会根据指定的size大小进行逐步删除,会将对IO造成的影响降到最低。
Usage: truncate OPTION... FILE... Shrink or extend the size of each FILE to the specified size A FILE argument that does not exist is created. If a FILE is larger than the specified size, the extra data is lost. If a FILE is shorter, it is extended and the extended part (hole) reads as zero bytes. Mandatory arguments to long options are mandatory for short options too. -c, --no-create do not create any files -o, --io-blocks treat SIZE as number of IO blocks instead of bytes -r, --reference=RFILE base size on RFILE -s, --size=SIZE set or adjust the file size by SIZE --help display this help and exit --version output version information and exit SIZE may be (or may be an integer optionally followed by) one of following: KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y. SIZE may also be prefixed by one of the following modifying characters: `+' extend by, `-' reduce by, `<' at most, `>' at least, `/' round down to multiple of, `%' round up to multiple of. Report truncate bugs to bug-coreutils@gnu.org GNU coreutils home page: <http://www.gnu.org/software/coreutils/> General help using GNU software: <http://www.gnu.org/gethelp/> For complete documentation, run: info coreutils 'truncate invocation'