利用硬链接和truncate降低drop table对线上环境的影响 众所周知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、建立硬链接。
ln table.ibd table.idb.hdlk
2、mysql执行drop table操作。
drop table if exists tablename;
3、使用truncate删除物理文件。
truncate -s xxxG filename

了解下truncate

此命令不仅能把文件的数据删成0字节,还可以缩减(甚至扩大)文件至指定的大小(通过 -s 选项指定文件大小值)

[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$echo -n 12345678 >test
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$cat test
12345678
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$truncate -s 4 test
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$cat test
1234
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$ls -l test
-rw-r--r-- 1 zhiqian.ly users 4 Mar 30 21:03 test
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$truncate -s 1M test
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$cat test
1234
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$ls -l test
-rw-r--r-- 1 zhiqian.ly users 1048576 Mar 30 21:03 test
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$wc -c test
1048576 test
[zhiqian.ly@dbconsole.sqa.bja /home/zhiqian.ly]
$du test
4 test

这里还可以看到一个“奇怪”的现象,本来已经缩至4字节的文件,把它扩展成1M以后,ls 和 wc 的结果显示大小确实是1M,但是 du 的结果却发现大小还是4字节。这也是要注意的地方之一,这种文件称为“空洞文件”,也就是说,文件的部分内容并没有实际存在于硬盘上(即没有分配对应的inode),只是“声称”有1M的大小而已。对于不存在于硬盘上的那部分字节,如果去读的话,也是不会报错的,会读到全0的数据。

删除代码

#!/bin/bash
TRUNCATE=/usr/local/bin/truncate
for i in `seq 2194 -10 10 `; #从2194 开始每次递减10 ,输出结果见下面
do
sleep 2
echo "$TRUNCATE -s ${i}G /tmp/ep_bak.ibd.hdlk "
$TRUNCATE -s ${i}G /tmp/ep_bak.ibd.hdlk
done

其实硬链接和drop table就不用多说了,当多个文件共同指向同一inode,inode链接数N>1,删除任何一个文件都是巨快因为,此时删除的仅仅是指向inode的指针而当N=1时,则不一样了,此时删除的文件相关的所有数据块,所以慢在建立硬链接之后,mysql会认为rm了硬链接文件之后就算操作完毕,不会真正去删除物理文件从而提高了速度。但是对于服务器来说,实际的物理文件还在,如果手动rm,还是会产生很多的io影响,这时候就用到了truncate这个工具。这个工具会根据指定的size大小进行逐步删除,会将对IO造成的影响降到最低。

硬链接与软链接的联系与区别

我们知道文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、所有者等信息。在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。下图展示了程序通过文件名获取文件内容的过程。

通过文件名打开文件

为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。若一个 inode 号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名(见 图 2.hard link 就是 file 的一个别名,他们有共同的 inode)。硬链接可由命令 link 或 ln 创建。如下是对文件 oldfile 创建硬链接。

ln oldfile newfile

由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性: 文件有相同的 inode 及 data block; 只能对已存在的文件进行创建; 不能交叉文件系统进行硬链接的创建; 不能对目录进行创建,只可对文件创建; 删除一个硬链接文件并不影响其他有相同 inode 号的文件。

软链接与硬链接不同,若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块(见 图 5 )。因此软链接的创建与使用没有类似硬链接的诸多限制: 软链接有自己的文件属性及权限等; 可对不存在的文件或目录创建软链接; 软链接可交叉文件系统; 软链接可对文件或目录创建; 创建软链接时,链接计数 i_nlink 不会增加; 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。

软链接的访问

参考:

【MySQL】drop大表的更多相关文章

  1. MySQL DROP 大表时的注意事项

    对于表的删除,因为InnoDB引擎会在table cache层面维护一个全局独占锁一直到DROP TABLE完成为止,这样,对于表的其他操作会被HANG住.对于较大的表来说,DROP TABLE操作可 ...

  2. mysql删除大表更快的drop table办法

    mysql删除大表更快的drop table办法 参考资料:https://blog.csdn.net/anzhen0429/article/details/76284320 利用硬链接和trunca ...

  3. MySQL DROP TABLE操作以及 DROP 大表时的注意事项【转】

    删表 DROP TABLE Syntax DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCAD ...

  4. MySQL DROP TABLE操作以及 DROP 大表时的注意事项

    语法: 删表 DROP TABLE Syntax DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CA ...

  5. MySQL删除大表时潜在的问题(drop table,truncate table)

    来源于:https://www.cnblogs.com/CtripDBA/p/11465315.html,侵删,纯截图,避免吸引流量之嫌 case1,删除大表时,因为清理自适应hash索引占用的内容导 ...

  6. MySQL在线大表DDL操作

    在线大表DDL操作的方法: 1.主从架构轮询修改 需要注意: a.主库会话级别的记录binglog的参数关闭 b.500\502错误异常捕捉 c.检查备库的second behind master是否 ...

  7. MySQL在线大表DDL操作 (转)

    http://www.cnblogs.com/janehoo/p/5382474.html 线大表DDL操作的方法: 1.主从架构轮询修改 需要注意: a.主库会话级别的记录binglog的参数关闭 ...

  8. mysql删除大表

    在mysql中遇到一个大表,大概有17G左右,在对这个表进行查询.修改时均遇到了很大的困难,于是想着删除这张表.通常的删除操作可以通过delete.drop.truncate操作,试了这三个命令,但是 ...

  9. MySQL 对于大表(千万级),要怎么优化呢?

    http://www.zhihu.com/question/19719997 提问:如何设计或优化千万级别的大表?此外无其他信息,个人觉得这个话题有点范,就只好简单说下该如何做,对于一个存储设计,必须 ...

随机推荐

  1. ASP.NET空网页生成默认代码注释

    当在Visual Studio下生成ASP.NET空网页时,默认生成代码: <%@ Page Language="C#" AutoEventWireup="true ...

  2. 【LeetCode】Roman to Integer & Integer to Roman

    Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within t ...

  3. BackTrack5-r3汉化

    进入BT系统图形模式,将语言包1和2拖进BT图形桌面. 所需文件包地址:http://pan.baidu.com/s/1i3ouc9v(64位更新包)将语言包1里的全部文件复制粘贴到:/var/cac ...

  4. flash 居中问题

    如果舞台是1000的宽度,要剧中比较容易 mc1.x = (1000-400)/2; 这样就居中了,来看原理,首先我们要舞台居中,很容易就想到一个数字 1000/2 结果是500 但是x对舞台的中央是 ...

  5. 百川sdk----自己的WebViewClient不被执行

    我在百川sdk的旺旺群中,追问这个问题N多次,一直没有人答复,哎,凡事都要靠自己..... 1.先查看下百川sdk中,是怎么处理咱们传递过去的 WebViewClient public class l ...

  6. isKindOfClass,isMemberOfClass

    - (BOOL)isKindOfClass:(Class)aClass; - (BOOL)isMemberOfClass:(Class)aClass; 特点: 1.isKindOfClass   判断 ...

  7. Iso-Seq学习

    SMRT portal安装教程: http://www.pacb.com/wp-content/uploads/2015/09/SMRT-Analysis-Software-Installation- ...

  8. 导出excel表格。

    导出也做了很多遍了,还是发现好记性不如烂笔头,还是记下来. public void exportLog(HttpServletRequest request,HttpServletResponse r ...

  9. UML和UP简介(转载)

    UML(统一建模语言,Unified Modeling Language)是用于系统的可视化建模语言.  UP(统一过程,Unified Process)是通用的软件开发过程. 很多人或书籍过大的夸大 ...

  10. sql中对于case when...then...else...end的写法和理解

    查询配件主数据表(tbl_part_base_info)的所有数据和配件是否有物料(物料表(tbl_material)中有配件主数据表的part_no,就表示有物料,反之,则表示没有物料),用sql中 ...