硬链接原理快速删除MySQL大文件

背景:
因为一个收集集团机器的历史性能的数据库的一个表涨到2.2 T,而磁盘空间总共2.6 T,和开发讨论之后决定废弃该表,对数据进行清理。问题是如何在生产环境下删除2.2 T 的文件并不能影响数据库服务器的IO性能?
这里给大家介绍一个使用硬链接和truncate 工具处理删除大数据文件的方法。

原理:
当多个文件名同时指向同一个INODE时,这个INODE的引用数N>1, 删除其中任何一个文件名都会很快。因为其直接的物理文件块没有被删除.只是删除了一个指针而已;当INODE的引用数N=1时, 删除文件需要去把这个文件相关的所有数据块清除,所以会比较耗时;

实现:
1. 创建tmp 表并 rename 表

mysql> rename table ep to ep_bak;
Query OK, 0 rows affected (0.07 sec)
mysql> rename table ep_tmp to ep;
Query OK, 0 rows affected (0.01 sec)

 
2. 对bak表创建硬链接

# ln ep_bak.ibd ep_bak.ibd.hdlk  //建立个ep_bak.idb.hdlk硬链接指向ep_bak.idb
# ll ep_bak.*
-rw-rw---- 1 mysql mysql          9023 Jul 28  2011 ep_bak.frm
-rw-rw---- 2 mysql mysql 2356792000512 Nov 30 18:05 ep_bak.ibd
-rw-rw---- 2 mysql mysql 2356792000512 Nov 30 18:05 ep_bak.ibd.hdlk

 
3. 删除表ep_bak,这个方法,我没有去试,因为还要搞个shell,觉得麻烦。我是通过rsync来实现删除的。
mysql> drop table ep_bak;
Query OK, 0 rows affected (0.99 sec)
1秒不到就删除完成;DROP TABLE就不用再HANG这么久了。但table是删除了,数据文件还在,所以最后你还需要将数据文件ep_bak.idb.hdlk给删除掉。如rm ep_bak.idb.hdlk
注意,表的大小为2194G,直接rm 必然会对数据库服务器的IO性能造成压力,因此我们使用coreutils 工具集中的truncate 对大文件进行shrink

coreutils安装
# wget http://ftp.gnu.org/gnu/coreutils/coreutils-8.9.tar.gz
# tar -zxvf coreutils-8.9.tar.gz 
# cd coreutils-8.9
# ./configure
# make

 
脚本对ep_bak.ibd.hdlk 进行shrink,脚本如下

#!/bin/bash
TRUNCATE=/usr/local/bin/truncate
for i in `seq 2194 -10 10 `; #从2194 开始每次递减10 ,输出结果见下面
do 
  sleep 2
  echo "$TRUNCATE -s ${i}G /home/mysql/data3306/mysql/monitor/ep_bak.ibd.hdlk "
  $TRUNCATE -s ${i}G /home/mysql/data3306/mysql/monitor/ep_bak.ibd.hdlk
done

 
使用truncate 工具删除数据时服务器IO负载,并未对服务器造成影响
truncate

附录:
附录1.第3步删除数据文件ep_bak.idb.hdlk也可以选择rsync来删除,确实比rm快多了。G级文件简直就是秒删。rsync删除ep_bak.idb.hdlk文件,请参考”rsync快速删除大文件

附录2.如果做主从,主通过建硬链接来快速删除表,那从mysql呢?会不会有影响?还没去试!!!

原文参考:硬链接原理快速删除MySQL大文件

发表评论

邮箱地址不会被公开。 必填项已用*标注