MySQL DROP TABLE操作以及 DROP 大表時的注意事項


語法:

刪表

DROP TABLE Syntax
DROP [TEMPORARY] TABLE [IF EXISTS]
    tbl_name [, tbl_name] ...
    [RESTRICT | CASCADE]

可一次刪除一張或多張表。需具有所刪除表上的DROP權限。

表定義文件和數據文件均被移除。表被刪除后表上的用戶權限不會被自己主動刪除。

參數里表中指定的表名不存在則報錯,但對於存在的表仍會刪除。可通過指定IF EXISTS阻止表不存在時引發的錯誤(此時對於不存在的表僅產生一個NOTE)。對於分區表。除了移除表定義,分區、數據外還移除與之關聯的分區定義文件(.par)。

在MySQL5.6中參數[RESTRICT | CASCADE]不做不論什么事情。

[TEMPORARY] keyword表明僅僅刪暫時表,語句不會結束正在進行的事務(MySQL中DDL語句會隱式提交)。不會進行權限檢查。


刪庫
DROP DATABASE Syntax
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name...
刪除指定庫中的表之后刪除庫。需具有庫上的DROP權限。

庫被刪除后庫上存在的用戶權限不會被自己主動刪除。IF EXISTS用於阻止庫名不存在時引起的錯誤。庫被刪除后默認庫會被重置。

若在使用了符號鏈接的庫上運行DROP DATABASSE 鏈接和原始數據庫都會被刪除。命令返回被移除的表數量。
該命令會從指定的數據庫文件夾中移除常規操作時MySQL自己產生的文件和文件夾。如:.BAK .DAT .HSH .MRG. MYD .MYI .TRG .TRN .db.frm .ibd .ndb .par若存在db.opt也相同會刪除。若數據庫文件夾中存在其它非MySQL本身產生的文件或文件夾。則整個數據庫文件夾不會被移除。此時,需手動清理剩余的文件並又一次執行DROP DATABASE語句。
刪除數據庫並不會移除庫中創建的暫時表。暫時表在SESSION結束時自己主動被清理或者顯示的通過DROP TEMPORARY TABLE 刪除。

刪除大表的注意事項
對於表的刪除。由於InnoDB引擎會在table cache層面維護一個全局獨占鎖一直到DROP TABLE完畢為止。這樣。對於表的其它操作會被HANG住。對於較大的表來說,DROP TABLE操作可能須要非常長的時間。因此須要一種有效的辦法來提升大表的刪除速度,以盡可能減少HANG住的時間。能夠通過設置硬鏈接來達到此目的。


比方有一個例子表:
example_table

使用InnoDB引擎且指定innodb_file_per_table=ON時在數據文件夾中與該表相應的有例如以下兩個文件。分別為表定義文件和數據文件。


sudo ls  -lh /data/mysql/testdb
-rw-rw---- 1 mysql mysql 8.4K Oct 28 13:26 example_table.frm
-rw-rw---- 1 mysql mysql 100G Oct 28 13:26 example_table.ibd
該表有100G這么大。直接使用DROP TABLE來完畢刪表動作,那么這條語句要運行非常長時間。此時便能夠通過在該表相應的數據文件上設置硬鏈接來進行刪除。


sudo ln /data/mysql/testdb/example_table.ibd /data/mysql/testdb/example_table.ibd.hdlk
sudo ls  -lh /data/mysql/testdb
-rw-rw---- 1 mysql mysql 8.4K Oct 28 13:26 example_table.frm
-rw-rw---- 2 mysql mysql 100G Oct 28 13:26 example_table.ibd
-rw-rw---- 2 mysql mysql 100G Oct 28 13:26 example_table.ibd.hdlk
發現多了一個example_table.ibd.hdlk文件,且example_table.ibd.hdlk和example_table.ibd的innode均為2。也即當有多個文件名稱(如硬鏈接)指向同一innode時,這個innode的引用數大於1。此時,刪除當中不論什么一個文件名稱都僅僅會刪除指向innode的指針而並不會直接刪除物理文件塊。因此會很快。直至innode的引用計數等於1時才會真正刪除相應的物理文件塊。真正刪除物理文件塊時才會比較耗時。



在建立了硬鏈接后再運行DROP TABLE操作:

DROP TABLE example_table;
發現會非常快的完畢。查看相應的表定義和數據文件:
sudo ls  -lh /data/mysql/testdb
-rw-rw---- 1 mysql mysql 100G Oct 28 13:26 example_table.ibd.hdlk
僅僅剩下example_table.ibd.hdlk,且innode的引用計數變為了1。

也即剛才的DROP TABLE操作實施刪除了物理文件的一個指針example_table.ibd ,因而很快。



剩下的任務就是刪除真正的物理文件了,由於此時innode的引用計數已經變為了1。直接刪除example_table.ibd.hdlk便會真正的刪除物理文件。

但由於物理文件較大。刪除大文件仍會引起較高的磁盤IO開銷。

因此能夠使用少量逐次刪除的方式來刪除大的數據文件。truncate工具能夠用於添加或縮減指定文件的尺寸,能夠用於此目的:

for i in `seq 100 -1 1 ` ;do sleep 2;sudo truncate -s ${i}G /data/mysql/testdb/example_table.ibd.hdlk;done
sudo rm -rf /data/mysql/testdb/example_table.ibd.hdlk;
從100G開始。每次縮減1G,停2秒,繼續,直到文件僅僅剩1G,最后使用rm命令刪除剩余的部分。



對於整個數據庫的刪除能夠先刪除當中較大的表。最后在運行DROP DATABASE刪除整個庫。對大表的刪除可參見上面的方法。










免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM