shell脚本删除线上MySQL大批量数据

来源:互联网 发布:linux mysql 安装包 编辑:程序博客网 时间:2024/06/06 02:04
【需求】
有时线上会有这种需求:
将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/


0 0