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即为上条命令查到的
     
  • 相关阅读:
    centos6升级python
    MySQL的BLOB类型(解决mysql不支持mb4编码的时候存储emoji表情问题)
    librdkafka安装和php扩展php-rdkafka安装
    Mac High Sierra 降级安装Mac Sierra
    mysql常用命令
    PHP_CodeSniffer 安装和phpstorm配置
    SSH登录异常(someone is doing something nasty)
    java并发 —— Lock
    java 并发——线程
    java 并发——内置锁
  • 原文地址:https://www.cnblogs.com/alipayhutu/p/3292031.html
Copyright © 2011-2022 走看看