您的位置:首页 > 运维架构 > Shell

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

2017-03-24 16:28 204 查看
【需求】

有时线上会有这种需求:

将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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql shell