mysql刪除大表更快的drop table辦法

2021-08-04 12:57:51 字數 4516 閱讀 8927

利用硬鏈結和truncate降低drop table對線上環境的影響

在drop table的時候,所有程序不管是ddl還是dml都被hang起;直到drop結束才繼續執行;

這是因為innodb會維護乙個全域性獨佔鎖(在table cache上面),直到drop table完成才釋放。

在我們常用的ext3,ext4,ntfs檔案系統,要刪除乙個大檔案(幾十g,甚至幾百g)還是需要點時間的。

下面我們介紹乙個快速drop table 的方法; 不管多大的表,innodb 都可以很快返回,表刪除完成;

嘗試5:又找了另一位大牛,這下得解救了,翻身農奴了,拜啊,三柱香,牛!想知道是怎麼做的嗎?我知道你想,嘻嘻,別著急,是這樣的,建硬鏈結

在db server上,找到mytable表對應的檔案,我的是/data/mysql3306/data/mydatabase/。

在這個目錄下,我們可以看到以下記錄,真的是390g!嚇死銀呀! 

-rw-------1oracle oinstall46672aug 30 15:42mytable.frm

-rw-------1oracle oinstall391466975232aug 30 15:42mytable.ibd

以上記錄中,1表示該檔案只有乙個鏈結(沒有另外的人鏈結到它,要刪就是真的刪檔案本身了哦),怪不得我執行truncate/drop這麼慢,原來背後就是在刪這個東東呀!

那怎麼辦呢?能不能繞過,不刪檔案本身,先快速把錶drop掉該多好呀。那麼建硬鏈結ln可以完成。

ln mytable.ibd  mytable.ibd.h

lnmytable.frmmytable.frm.h

相當於乙個檔案被兩個索引鏈結著,要刪就是只刪鏈結,而不是刪檔案本身了,直到只有乙個人鏈結它,才會是真的刪呢。

這時再執行drop表的動作,別提多快了,oh my god,快到驚人,mytable.ibd瞬間它不見了,不見了!

最後別忘了把那個大大的「真檔案」手工刪刪掉 

rm -f mytable.ibd.h

rm -f mytable.frm.h

所以,同學們,鄉親們,最最親愛的屌絲們,我痛完了,也絮叨完了,希望你疼的時候能看到這篇部落格,幫你節約哪怕一杯茶的時間,也值了。共勉!

眾所周知drop table會嚴重的消耗伺服器io效能,如果被drop的表容量較大,甚至會影響到線上的正常。

首先,我們看一下為什麼降容量大的表會影響線上服務

直接執行drop table,mysql會將表定義和表資料全都刪除,包括磁碟上的物理檔案,也包括緩衝池中的記憶體資料。

這麼分兩步,第一步從緩衝池中刪除,這會涉及到table_cache的鎖,如果持有table_cache的鎖,這將導致其他查詢都無法執行。這種情況在沒有innodb_per_table之前尤為嚴重。另外,mysql5.5.23之後新增lazy drop table功能,這個功能用來解決互斥的lru列表。其中心思想就是加鎖,找到需要被刪除的頁面,刪除1024個頁之後釋放鎖讓其他執行緒工作,之後迴圈而percona的lazy drop處理起來更優雅一些,其會先加鎖,然後找到需要被刪除的頁面,標記,釋放鎖,後台慢慢刪除。

之後就是第二步,這步在大容量表的時候更為消耗時間,那就是在os上刪除物理檔案。大家都知道在ext3上rm乙個200g的檔案會非常耗時,這是由於ext3儲存資料的結構導致,如果乙個很大的檔案,ext3的i_block無法直接存放,需要多層巢狀才能完全儲存下,在這種情況下由於對映的層次多,並且由於多層對映也不會是順序儲存的,就導致了很大的隨機io,這就導致了刪除物理檔案非常慢的現象。在這種情況下,建議公升級到ext4,這是由於ext4比ext3的使用程度分配儲存空間,其最大的優勢就是順序儲存。

知道了原因,我們來說說如何解決具體步驟如下:

1,建立硬鏈結。

ln table.ibd table.idb.hdlk
2,mysql執行drop table操作。

drop 

table

if exists tablename;

3,使用截斷刪除物理檔案。

truncate -s 1024 * 1024 * 4 filename
其實硬鏈結和drop table就不用多說了,在建立硬鏈結之後,mysql會認為rm了硬鏈結檔案之後就算操作完畢,不會真正去刪除物理檔案從而提高了速度。但是對於伺服器來說,實際的物理檔案還在,如果手動rm,還是會產生很多的io影響,這時候就用到了截斷這個工具。這個工具會根據指定的尺寸大小進行逐步刪除,會將對io造成的影響降到最低。

用法:truncate option ... file ...

縮小或擴充套件每個file的大小到指定的大小

建立不存在的file引數。

如果檔案大於指定的大小,則額外的資料將丟失。

如果檔案較短,則延長部分(孔)

讀為零位元組。

長期期權的強制性論據也適用於

短期期權。

-c,--no建立 做

不建立任何檔案

-o,--io- 塊對待size作為io塊而不是位元組數

-r,--reference = 上的rfile的rfile基底大小

-s,--size = size通過size設定或調整檔案

大小 - 幫助顯示此幫助和退出

- 版本輸出版本資訊並退出

size可以是(或可以是可選的後面的整數)以下之一:

對於g,t,p,e,z,y,

kb 1000,k 1024,mb 1000 * 1000,m 1024 * 1024等。

size也可以字首為以下修改字元之一:

` + '

延伸,` -

'減少,`< '

至多,`>

' 至少,

` / '

迴圈到多個,'%

' 輪到多個。

報告截斷bug - [email protected]

gnu coreutils主頁: http://

www.gnu.org/software/coreutils/>

一般幫助使用gnu軟體://

www.gnu.org/gethelp/>

有關完整的文件,請執行:info coreutils '

截斷呼叫

[email protected] : test 21:39:34> drop table tt ;

query ok, 0 rows affected (25.01 sec)

刪除乙個11g的錶用時25秒左右(硬體不同,時間不同);

下面我們來對另乙個更大的表進行刪除;

但之前,我們需要對這個表的資料檔案做乙個硬連線:

root@ # ln stock.ibd stock.id.hdlk

root@ # ls stock.* -l

-rw-rw—- 1 mysql

mysql        9196 apr 14 23:03 stock.frm

-rw-r–r– 2 mysql mysql 19096666112 apr 15 09:55 stock.ibd

-rw-r–r– 2 mysql mysql 19096666112 apr 15 09:55 stock.id.hdlk

你會發現stock.ibd的inodes屬性變成了2;

[email protected] : test 21:39:34> drop table stock ;

query ok, 0 rows affected (0.99 sec)

1秒不到就刪除完成; 也就是drop table不用再hang這麼久了。

但table是刪除了,資料檔案還在,所以你還需要最後資料檔案給刪除。

至於原理: 就是利用os hard link的原理,

當多個檔名同時指向同乙個inode時,這個inode的引用數n>1, 刪除其中任何乙個檔名都會很快.

因為其直接的物理檔案塊沒有被刪除.只是刪除了乙個指標而已;

當inode的引用數n=1時, 刪除檔案需要去把這個檔案相關的所有資料塊清除,所以會比較耗時;

mysql刪除大表更快的drop table辦法

曾經發文介紹過,drop table 特別是碰到大表時,在drop table 過程中,所有操作都會被hang住。這是因為innodb會維護乙個全域性獨佔鎖 在table cache上面 直到drop table完成才釋放。在我們常用的ext3,ext4,ntfs檔案系統,要刪除乙個大檔案 幾十g,...

MySQL 儲存過程刪除大表

1 許可權問題 alter routine 編輯或刪除儲存過程 create routine 建立儲存過程 execute 建立儲存過程 2 儲存過程相關的一些命令 show procedure status g 檢視資料庫中有哪些儲存過程 show procedure status where d...

mysql 清空 MySQL大表清空和刪除正確方法

mysql大表清空和刪除正確方法 1 清空大表 1.1 truncate 刪除表中的資料的方法有delete,truncate,其中truncate table用於刪除表中的所有行,而不記錄單個行刪除操作。truncate table 與沒有 where 子句的 delete 語句類似 但是,tru...