truncate/drop表非常慢,怎么辦?用硬鏈接,極速體驗


     這個這個,我必須花巨大篇幅,記錄下今天清空表記錄的英雄壯舉,可知道一個drop操作,執行了一下午啊一下午,這是要急出翔的節奏。。呵呵,下面開始

 

我的需求:某表因歷史原因,積壓了1億條記錄,約占360G空間。我要清掉它,就是這么簡單。

嘗試1:作為DB小菜,首先想到的,當然是delete命令。於是歡快的執行了delete from mytable; 知道嗎?一杯茶都喝完了,它還沒有執行完。我的尊嚴受到了挑戰,捉急了,開始google。

嘗試2:好,換用truncate命令。truncate table mytable; 知道嗎?第二壞茶喝完了,它還沒有執行完。快急出翔了,繼續google。

嘗試3:好,干脆drop表好了。drop table mytable; 知道嗎?第三杯茶喝完了,它還沒有執行完。這下快嚇尿了,這是什么情況。。。趕快找大牛問

          當然,drop之前別忘了先備份一下表結構,一會兒drop完了還得重新建表,那得多麻煩呀,嘿嘿

          create table mytable_bak like mytable; // 備份

          drop table mytable;                      // 刪表 

 

          alter table mytable_bak rename to mytable;  // 重新命名

嘗試4:大牛說,不妨改一下這兩個開關,可以加速drop。於是,又等了10min,窗外雨都下停了,還是沒有執行完。。。

        show variables like '%lazy%';
        show variables like '%file_per%';
        set  global innodb_lazy_drop_table=1;  // 默認值是0
         set global innodb_file_per_table=OFF; //默認值是ON
嘗試5:又找了另一位大牛,這下得解救了,翻身農奴了,拜啊,三柱香,牛!想知道是怎么做的嗎?我知道你想,嘻嘻,別着急,是這樣的,建硬鏈接
          在DB server上,找到mytable表對應的文件,我的是/data/mysql3306/data/mydatabase/。
          在這個目錄下,我們可以看到以下記錄,真的是390G!嚇死銀呀! 
          -rw------- 1 oracle oinstall  46672 Aug 30 15:42 mytable.frm 
          -rw------- 1 oracle oinstall 391466975232 Aug 30 15:42 mytable.ibd 
          以上記錄中,1表示該文件只有一個鏈接(沒有另外的人鏈接到它,要刪就是真的刪文件本身了哦),怪不得我執行truncate/drop這么慢,原來背后就是在刪這個東東呀!
          那怎么辦呢?能不能繞過,不刪文件本身,先快速把表drop掉該多好呀。那么建硬鏈接ln可以完成。
         ln mytable.ibd  mytable.ibd.h
         ln mytable.frm  mytable.frm.h
         相當於一個文件被兩個索引鏈接着,要刪就是只刪鏈接,而不是刪文件本身了,直到只有一個人鏈接它,才會是真的刪呢。
          這時再執行drop表的動作,別提多快了,oh my god,快到驚人,mytable.ibd瞬間它不見了,不見了!
          最后別忘了把那個大大的“真文件”手工刪刪掉 
         rm -f mytable.ibd.h
         rm -f mytable.frm.h
 
          所以,同學們,鄉親們,最最親愛的屌絲們,我痛完了,也絮叨完了,希望你疼的時候能看到這篇博客,幫你節約哪怕一杯茶的時間,也值了。共勉!
 
 
 
 
         正題說完了,說點題外話,一些mysql常用命令:
【1】如何查看表記錄數、所占空間等。這個在巨表面前,用select count(*) from mytable 神馬的都弱爆了,用這個:
root@ information_schema  04:24:23>SELECT TABLE_NAME,TABLE_ROWS,DATA_LENGTH FROM TABLES WHERE TABLE_SCHEMA='mydatabase' AND TABLE_NAME='mytable';
【2】如何查看mysql連接情況,哪些用戶連着,分別用了多少連接數
root@information_schema 01:31:12>select substr(host,1,locate(':',host)-1),user, count(*) from processlist group by substr(host,1,locate(':',host)-1), user order by count(*) desc, host desc;
【3】如何斷開這些連接呢?
root@(none) 01:26:08>show processlist;  // 看到相關連接的id
root@(none) 01:26:08>kill id;                   // 斷掉連接,id即為上條命令查到的
 


免責聲明!

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



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