这篇文章主要讲解了“MySQL大表删除问题的解决方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL大表删除问题的解决方法”吧!
(1)、mysql如何删除表
(2)、删除大表如何优化、解决
删除表原理上分为2部分:
<1>buffer pool页面清除过程。
在删除表的时候,Innodb 会将文件在buffer pool中对应的页面清除。对于删除表的页面清除,只需要将页面从flash队列中删除即可,而不需要去做flush操作,减小对系统的冲击。
问题1:如果buffer pool很大,或者是在buffer pool中有很多需要被flush的页面,那么此时遍历扫描页面时就会占用比较长的时间,导致其他事务在用到相应buffer pool实例时被阻塞,从而影响整个数据库性能。
优化:涉及源码,优化困难
<2>删除ibd磁盘文件的过程。
问题1:表文件过大,直接删除会瞬时占用大量IO,造成IO阻塞
优化:使用硬链
原理:一个磁盘上的文件,可以由多个文件系统的文件引用,这多个文件的完全相同的,都指向同一个磁盘上的文件,当我们删除任何一个文件的时候,都不会影响真实的文件,只是会将其引用数据减1,只有当被引用数目变为1的时候,再次删除文件,才会真正被删除。删除时,这两种情况的区别很明显,一个是在减少被引用数目,一个是真正做IO来删除它
操作:
ln /data/mydata/my3306/testdb/table1.ibd /data/mydata/my3306/testdb/table1.ibd.hdlk
ls -lh /data/mydata/my3306/testdb 查看文件引用数(应该为2)
问题2:做完硬链,真正的大文件删除问题,直接rm 删除,会造成IO瞬时高峰
优化:使用工具,多次少量的删除
原理:利用系统文件的truncate,脚本工具为slowrm
缓解大表删除带来的IO瞬间压力
<1>将大文件按照指定速度进行删除,降低IO瞬间压力
先简要介绍下slowrm工具开发的背景。
我们曾在《linux_mysql_DROP_TABLE操作步骤》中提到,对于大表的删除,应当先建立硬链,drop table后,再删除表数据文件。
对于大表的数据文件,可能会达到10G,也可以是100G级别,甚至更大。在linux下,这样的大文件在使用rm时,无疑会导致IO资源被强行占用,表现为硬盘的io_util基本上是100%左右,会对其它IO操作造成阻塞。更可怕的是,rm单个文件的过程是个原子过程,无法使用kill或kill -9来杀死rm进程,只能乖乖的等待它结束。
如果是在繁忙的线上服务所在的机器上做这样的删除操作,很可能会对线上服务产生影响。因此需要有一个平滑删除大文件的方案。而这样的方案最终是与数据库无关的,而是一个通用方案。
对于删除大文件的操作,采用每次将文件截断一点,分多次截断,最终直至文件大小被截断为0。
如下面的过程示例:
block_size = 1024576bytes;
while file_size >=block_size
begin
ftruncate (file, new_size);
(其中(old_size -new_size = block_size)
sleep 0.05 seconds;
end
ftruncate(file, 0);
因为既然rm一个文件是不可中断的,那么我们就将删除过程打散,分多次删除一个,每次删除一点。幸好现在的linux提供了支持该思路的API,truncate/ftruncate函数,可以对文件截断至任意长度()。经过测试,发现每次截断一点,分多次截断,最终直至文件大小被截断为0,这样删除大文件需要更多的时间,但是对磁盘IO的影响却大大减小了。因此采用该思路是可行的。
slowrm [OPTIONS] FILES
对删除文件的方式与rm类似。
该工具的使用主要涉及两个参数:
-b #size
每次需要截断掉的文件大小,单位为字节,参数值需要是整数,默认值4096 * 256Bytes( = 1MB);
-s #seconds
每两次截断操作之间的时间间隔,单位为秒,参数值可以为小数。这两个参数用以控制删除速度,及删除过程对磁盘IO的压力。默认值0.1 second
-h, --help
查看帮助信息。
直接输入slowrm,或输入slowrm –h或slowrm --help可以查看帮助。
实际上,可以看出,由#size * #seconds = #ioBPS Bytes/s,
即可计算得出每秒该操作消耗的IO吞吐量(字节数),也即大约每秒文件所减小的字节数。
可以看到默认删除速度是: 4096 * 256Bytes / 0.1second= 10MB/s,被删除的文件每秒钟可以减少10MB。
用户可以通过上述两个参数来控制删除的速度以及对磁盘IO的压力。
使用方式 | slowrm | rm | 备注 | |
提示是否删除 | 默认支持 | rm -i | 默认slowrm会询问用户是否删除每一个指定文件 | |
删除单个文件 | slowrm file | rm file | 相同 | |
删除多个文件 | 显示指定文件 | slowrm file1 file2 file3 | rm file1 file2 file3 | |
使用通配符 | slowrm file* | rm file* | ||
删除硬链 | 硬链数大于1 | 删除硬链同rm | 删除硬链 | 实际执行的就是unlink |
硬链数等于1 | 低速删除文件 | 全速删除文件 | 实质上在判断硬链数上逻辑是一样的,只是最后一个硬链的删除方式不同 | |
强制删除文件 |
slowrm -f slowrm --force |
rm -f rm --force | 相同 | |
控制删除速度 | 控制速度 | slowrm -s 0.1 -b 262144 file (2MB/s) | 不支持 | |
默认速度 |
slowrm file 对应参数-s 0.1 -b 1048576(10MB/s) | 一般使用默认参数即可 | ||
删除其他类型文件 | 目录,软链 | 不支持 | ||
递归删除目录 | rm -rf 目录 |
可见,一般情况下,还是使用rm删除即可。
在需要低IO负载删除大文件时,可以使用slowrm。
slowrm对于rm是起到一个补充的作用。
目前,该工具只支持删除具体常规文件,无法对目录进行递归删除,但可以支持对多个文件进行删除,如slowrm *.logmysql.err.2014*
也无法对软链接,文件等进行删除。
如果slowrm要删除的文件的硬链接数目大于1,那么就会直接删除该硬链;
如果待删除的文件硬链数目等于1,那么会按照平滑删除的方式,逐步截断该文件。
制造大文件
开始删除
大小情况
压力情况
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
1、开启一个screen
screen -S slowrm_test
2、开始删除文件
slowrm file
或者指定速度,正常默认即可(10MB/s)
感谢各位的阅读,以上就是“MySQL大表删除问题的解决方法”的内容了,经过本文的学习后,相信大家对MySQL大表删除问题的解决方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。