0
点赞
收藏
分享

微信扫一扫

MySQL物理删除大表文件的方式

目录

  • ​​MySQL Drop表的逻辑顺序​​
  • ​​Drop操作示例​​
  • ​​清除硬链接磁盘数据​​

MySQL Drop表的逻辑顺序

  1. 清除buffer pool中的缓存信息,需要在每个buffer pool实例中搜索到该表对应的数据页,将数据页从flush队列中移除
  • ​在移除过程中会对每个buffer pool持有全局锁​​,如果要移除的数据页过多,遍历时间则较长,导致其他事务被阻塞甚至数据库hang住
  • 可以增加innodb_buffer_pool_instances的数量来降低每个buffer pool的大小
  • ​buffer pool过大也同样会导致遍历的时间过长​
  1. 清除过程中还涉及对​​AHI(自适应hash索引)中对该表的数据​​,AHI占用总buffer pool的1/16的大小
  • 在并发小且数据库不是特别大的场景下建议关闭AHI特性
  • set global innodb_adaptive_hash_index=off
  1. 删除磁盘上对应的ibd文件
  • ​如果磁盘文件过大,会占用大量IO​
  • 使用Linux硬链接方式延迟删除物理文件

Drop操作示例

-- 先创建硬链接
ln sbtest1.ibd sbtest1.ibd.hdlk

-- 在数据库层执行drop
drop table sbtest.sbtest1;

清除硬链接磁盘数据

由于测试环境sbtest库较小,下面用dd快速造一个10G的大文件模拟磁盘数据删除操作

  • dd if=/dev/zero of=/tmp/test_data bs=1M count=10000
  • 分批次删除磁盘数据脚本示例

#!/bin/bash

## 记录执行开始时间
beginTime=`date +'%Y-%m-%d %H:%M:%S'`

## 指定文件路径及名称
truncateFile=/tmp/test_data

## 指定文件大小,单位GB
sizeOfGigaByte=10

## 判断文件是否存在,不存在直接退出
if [ ! -f ${truncateFile} ];then
echo "${truncateFile} File does not exist!!,Please Check Again!"
exit 1
fi

## 循环删除,表示总共10G,按每-1G来truncate数据,直到文件只剩1G后结束循环
for i in `seq ${sizeOfGigaByte} -1 1`;
do
## 每执行一次删除停1秒,减少IO压力
sleep 1
remain=${i}
echo "`date +'%Y-%m-%d %H:%M:%S'` The remaining data: ${remain}G"
truncate -s ${i}G ${truncateFile}
done

## 最后删除剩下的1G数据库
rm -rf ${truncateFile}
echo "${truncateFile} Has been deleted"

endTime=`date +'%Y-%m-%d %H:%M:%S'`

echo "Total Running Time(s):" $(($(date --date="$endTime" +%s)-$(date --date="$beginTime" +%s)))"s"

  • 脚本输出示例
  • MySQL物理删除大表文件的方式_硬链接



举报

相关推荐

0 条评论