1. 程式人生 > >shell指令碼刪除線上MySQL大批量資料

shell指令碼刪除線上MySQL大批量資料

【需求】
有時線上會有這種需求:
將A表中id欄位等於B表id欄位的記錄刪掉,A表和B表資料分佈在不同例項的不同庫裡,且資料量很大。

【解決辦法】
將B表的id欄位從備庫匯出,select into outfile
在A表所在例項test庫建立臨時表tmp_id,匯入資料,load data infile
根據關聯欄位刪除即可,關聯欄位要有索引

【指令碼實現】

為了減少對生產系統的IO衝擊,我們採取每次批量刪除前sleep一段時間,控制刪除的頻率。

下面使用shell指令碼實現一個兩表關聯刪除線上大批量資料的指令碼,已經在線上使用,效果還不錯。
#!/bin/bash
#需要修改下面幾個引數
#min_id 
#max_id
#del_counts
#SQL

db_user="root"
db_name="BSS"
db_host="127.0.0.1"
db_port="3306"
mysql="/ROOT/server/mysql/bin/mysql"

min_id=1                        #起始id
max_id=10000000         #結束id
del_counts=1000           #分多少批進行刪除,假如每次刪除10000條資料,一共10000000條資料,那麼這裡修改為1000
id_avg=$[max_id-min_id]
id_avg=$[id_avg/del_counts]
total_affect_rows=0
now=`date "+%Y-%m-%d %H:%M:%S"`
echo "[$now] delete begin......"

for ((i=1;i<=$del_counts;i++))
do
    if [ $i -eq $del_counts ];then
        end_id=$max_id
    else
        end_id=$[id_avg+min_id]
    fi
    affect_rows=`$mysql -u $db_user -h $db_host -P $db_port $db_name -N -e "delete a from tb_user a,test.tmp_id b where a.id=b.id and a.id>=$min_id and a.id<=$end_id;select row_count();"`   #具體SQL根據實際進行修改
    now=`date "+%Y-%m-%d %H:%M:%S"`
    echo "[$now] delete $affect_rows rows [id>=$min_id and id<=$end_id]"
    min_id=$[end_id+1]
    echo "sleep 1"
    sleep 1
    total_affect_rows=$[total_affect_rows + affect_rows]
done
now=`date "+%Y-%m-%d %H:%M:%S"`
echo "[$now] delete end......"
echo "total affect rows is: $total_affect_rows"

參考文章
https://zhuanlan.zhihu.com/p/20209766

http://blog.itpub.net/22664653/viewspace-759736/