shell指令碼刪除線上MySQL大批量資料
阿新 • • 發佈:2018-12-25
【需求】
有時線上會有這種需求:
將A表中id欄位等於B表id欄位的記錄刪掉,A表和B表資料分佈在不同例項的不同庫裡,且資料量很大。
【解決辦法】
將B表的id欄位從備庫匯出,select into outfile
在A表所在例項test庫建立臨時表tmp_id,匯入資料,load data infile
根據關聯欄位刪除即可,關聯欄位要有索引
#!/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
有時線上會有這種需求:
將A表中id欄位等於B表id欄位的記錄刪掉,A表和B表資料分佈在不同例項的不同庫裡,且資料量很大。
【解決辦法】
將B表的id欄位從備庫匯出,select into outfile
在A表所在例項test庫建立臨時表tmp_id,匯入資料,load data infile
根據關聯欄位刪除即可,關聯欄位要有索引
【指令碼實現】
為了減少對生產系統的IO衝擊,我們採取每次批量刪除前sleep一段時間,控制刪除的頻率。
#!/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/