zoukankan      html  css  js  c++  java
  • MySQL DROP 大表时的注意事项

      对于表的删除,因为InnoDB引擎会在table cache层面维护一个全局独占锁一直到DROP TABLE完成为止,这样,对于表的其他操作会被HANG住。对于较大的表来说,DROP TABLE操作可能需要很长的时间,因此需要一种有效的办法来提升大表的删除速度,以尽可能降低HANG住的时间。可以通过设置硬链接来达到此目的。比如有一个样例表:example_table

    使用InnoDB引擎且指定innodb_file_per_table=ON时在数据目录中与该表对应的有如下两个文件,分别为表定义文件和数据文件:

    1 sudo ls  -lh /data/mysql/testdb  
    2 -rw-rw---- 1 mysql mysql 8.4K Oct 28 13:26 example_table.frm  
    3 -rw-rw---- 1 mysql mysql 100G Oct 28 13:26 example_table.ibd 

      该表有100G这么大,直接使用DROP TABLE来完成删表动作,那么这条语句要执行很长时间。此时便可以通过在该表对应的数据文件上设置硬链接来进行删除。

    1 sudo ln /data/mysql/testdb/example_table.ibd /data/mysql/testdb/example_table.ibd.hdlk  
    2 sudo ls  -lh /data/mysql/testdb  
    3 -rw-rw---- 1 mysql mysql 8.4K Oct 28 13:26 example_table.frm  
    4 -rw-rw---- 2 mysql mysql 100G Oct 28 13:26 example_table.ibd  
    5 -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操作:

    1 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工具可以用于增加或缩减指定文件的尺寸,可以用于此目的:

    1 for i in `seq 100 -1 1 ` ;do sleep 2;sudo truncate -s ${i}G /data/mysql/testdb/example_table.ibd.hdlk;done  
    2 sudo rm -rf /data/mysql/testdb/example_table.ibd.hdlk;

      从100G开始,每次缩减1G,停2秒,继续,直到文件只剩1G,最后使用rm命令删除剩余的部分。

      对于整个数据库的删除可以先删除其中较大的表,最后在执行DROP DATABASE删除整个库,对大表的删除可参见上面的方法。

    转自《http://blog.csdn.net/zyz511919766/article/details/40539333》

  • 相关阅读:
    关于Java8:StreamAPI的一点记录
    关于JDBC的批量操作executeBatch()所引发sql语句异常
    [Java]直播方案----[接入环信聊天室]+[腾讯云直播]
    获取SpringCloud gateway响应的response的值,记录踩坑
    Spring Boot2.1.7启动zipkin-server报错:Error creating bean with name 'armeriaServer' defined in class path
    java.lang.IllegalArgumentException: Prometheus requires that all meters with the same name have the same set of tag keys.
    Spring Cloud Gateway报错:Unable to start embedded Tomcat
    poi设置Word页边距
    访问rabbitmq-server失败
    RabbitMQ获取队列的消息数目
  • 原文地址:https://www.cnblogs.com/polestar/p/6555080.html
Copyright © 2011-2022 走看看