原文地址:http://ace105.blog.51cto.com/639741/1172724
mysql在對(duì)大表做DROP TABLE 過(guò)程中,所有操作都會(huì)被HANG住。
這是因?yàn)镮NNODB會(huì)維護(hù)一個(gè)全局獨(dú)占鎖(在table cache上面),直到DROP TABLE完成才釋放。
在我們常用的ext3,ext4,ntfs文件系統(tǒng),要?jiǎng)h除一個(gè)大文件(幾十G,甚至幾百G)還是需要點(diǎn)時(shí)間的。
下面我們介紹一個(gè)快速DROP table 的方法; 不管多大的表,INNODB 都可以很快返回,表刪除完成;
實(shí)現(xiàn):巧用LINK(硬鏈接)
我們首先構(gòu)建一張大表
mysql>create table aa as select * from SuperAgentWebSite;
Query?OK,?5505 rows affected?(1.75?sec)
Records:?5505??Duplicates:?0??Warnings:?0
mysql>insert into aa select * from aa?;
Query?OK,?5505 rows affected?(1.60?sec)
Records:?5505??Duplicates:?0??Warnings:?0
mysql>insert into aa select * from aa?;
Query?OK,?11010 rows affected?(3.91?sec)
Records:?11010??Duplicates:?0??Warnings:?0
mysql>insert into aa select * from aa?;
Query?OK,?22020 rows affected?(8.02?sec)
Records:?22020??Duplicates:?0??Warnings:?0
mysql>insert into aa select * from aa?;
Query?OK,?44040 rows affected?(16.36?sec)
Records:?44040??Duplicates:?0??Warnings:?0
mysql>insert into aa select * from aa?;
Query?OK,?88080 rows affected?(34.15?sec)
Records:?88080??Duplicates:?0??Warnings:?0
查看一下表的大小
[root@db15?test]#?du?-sh?aa*
16K?aa.frm
3.8G????aa.ibd
關(guān)鍵地方來(lái)了,對(duì)aa表做一個(gè)硬鏈接
[root@db15?test]#?ln?aa.ibd??aa.hdlk
這個(gè)時(shí)候發(fā)現(xiàn)本身mysql的aa.ibd文件變小了。文件存貯到了我們的硬鏈接文件上。
[root@db15?test]#?du?-sh?aa*
16K?aa.frm
3.8G????aa.hdlk
刪除aa表,我們發(fā)現(xiàn)瞬間就搞定了。
mysql>drop table aa;
Query?OK,?0 rows affected?(0.33?sec)
最后去硬鏈接目錄下面把我們的硬鏈接數(shù)據(jù)文件aa.hdlk刪除掉。 我們發(fā)現(xiàn)上面刪除表的droptableaa;?只是刪除了aa.frm文件。
[root@db15?test]#?rm?-rfv?aa*
已刪除“aa.hdlk”
雖然DROP TABLE 多繞了幾步。(如果你有一個(gè)比較可靠的自運(yùn)行程序(自動(dòng)為大表建立硬鏈接,并會(huì)自動(dòng)刪除過(guò)期的硬鏈接文件),就會(huì)顯得不那么繁瑣。)
這樣做能大大減少M(fèi)YSQL HANG住的時(shí)間; 相信還是值得的。
至于原理: 就是利用OS HARD LINK的原理,
當(dāng)多個(gè)文件名同時(shí)指向同一個(gè)INODE時(shí),這個(gè)INODE的引用數(shù)N>1, 刪除其中任何一個(gè)文件名都會(huì)很快.
因?yàn)槠渲苯拥奈锢砦募K沒有被刪除.只是刪除了一個(gè)指針而已;
當(dāng)INODE的引用數(shù)N=1時(shí), 刪除文件需要去把這個(gè)文件相關(guān)的所有數(shù)據(jù)塊清除,所以會(huì)比較耗時(shí);