MySQL物理刪除大表檔案的方式
阿新 • • 發佈:2021-08-05
目錄
MySQL Drop表的邏輯順序
- 清除buffer pool中的快取資訊,需要在每個buffer pool例項中搜索到該表對應的資料頁,將資料頁從flush佇列中移除
在移除過程中會對每個buffer pool持有全域性鎖
,如果要移除的資料頁過多,遍歷時間則較長,導致其他事務被阻塞甚至資料庫hang住- 可以增加innodb_buffer_pool_instances的數量來降低每個buffer pool的大小
buffer pool過大也同樣會導致遍歷的時間過長
- 清除過程中還涉及對
AHI(自適應hash索引)中對該表的資料
- 在併發小且資料庫不是特別大的場景下建議關閉AHI特性
- set global innodb_adaptive_hash_index=off
- 在併發小且資料庫不是特別大的場景下建議關閉AHI特性
- 刪除磁碟上對應的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"
- 指令碼輸出示例