眾所周知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、建立硬鏈接。
table.ibd table.idb.hdlk
tablename;
truncate -s ** filename
其實硬鏈接和drop table就不用多說了,在建立硬鏈接之後,mysql會認為rm了硬鏈接文件之後就算操作完畢,不會真正去刪除物理文件從而提高了速度。但是對於服務器來說,實際的物理文件還在,如果手動rm,還是會產生很多的io影響,這時候就用到了truncate這個工具。這個工具會根據指定的size大小進行逐步刪除,會將對IO造成的影響降到最低。
options are mandatory -c, --no-create -o, --io--r, --reference=-s, --size=SIZE set or adjust the ----, K , MB *, M *, and so on + reduce by, `</-<http: General help using GNU software: <http: For complete documentation, run: coreutils