1. 程式人生 > 其它 >MySQL物理刪除大表檔案的方式

MySQL物理刪除大表檔案的方式

目錄

MySQL Drop表的邏輯順序

  1. 清除buffer pool中的快取資訊,需要在每個buffer pool例項中搜索到該表對應的資料頁,將資料頁從flush佇列中移除
    • 在移除過程中會對每個buffer pool持有全域性鎖,如果要移除的資料頁過多,遍歷時間則較長,導致其他事務被阻塞甚至資料庫hang住
      • 可以增加innodb_buffer_pool_instances的數量來降低每個buffer pool的大小
    • buffer pool過大也同樣會導致遍歷的時間過長
  2. 清除過程中還涉及對AHI(自適應hash索引)中對該表的資料
    ,AHI佔用總buffer pool的1/16的大小
    • 在併發小且資料庫不是特別大的場景下建議關閉AHI特性
      • set global innodb_adaptive_hash_index=off
  3. 刪除磁碟上對應的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"
  • 指令碼輸出示例
轉載請說明出處 |QQ:[email protected]