zoukankan      html  css  js  c++  java
  • 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即为上条命令查到的
     
  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/alipayhutu/p/3292031.html
Copyright © 2011-2022 走看看