数据库脚本

Mysql转移大数据脚本(按月分表专用)

2018-12-28  本文已影响31人  杍劼

背景:有时候我们需要将一些千万级甚至亿级的数据表进行数据转移,移动到分表当中。如果直接通过SELECT和INSERT结合会非常缓慢,本人用的是SELECT INTO OUTFILE和LOAD DATA INFILE结合。不过一开始我是每次查询一个月数据,直接导入到每月的分表当中,但是发现LOAD DATA语句是一个完整的事务,所以开销巨大,而且数据量巨大的情况下,很容易事务中断导致一个很长时间的锁。后来我想了个办法,将事务按天切分,如果一个月有30天,那么我让它顺序执行30个小事务,每个大约是几百万的数据,每次休眠个几秒钟,这样开销会小很多,最后数据可以成功导入到分表。

代码:

#!/bin/bash

# description:Mysql转移大数据脚本(按月分表专用)

# author:ZZJ

# time:2018-12-27

USER=root

PASSWORD=123456

HOST=127.0.0.1

MYSQL="/usr/local/percona/bin/mysql -u$USER -h$HOST -p$PASSWORD"

DATABASE="origin_platform"

TABLE="tb_sdk_role_login"

INDEX="FORCE INDEX(UK_G_S_U_E)"

YEAR="2018"

MONTH="08"

FIRST_DATE=$YEAR"-"$MONTH"-01"

DAY_NUM=`date -d "$FIRST_DATE +1 month -1 days" +%d`

CHILD_TABLE=$TABLE"_"$YEAR$MONTH

FILE_PATH="/backup/dao_date/"

echo "$DATABASE.$CHILD_TABLE Begin:"

#按月创建分表

CREATE_SQL="CREATE TABLE IF NOT EXISTS $DATABASE.$CHILD_TABLE LIKE $DATABASE.$TABLE"

#按日导出导入数据

for((DAY=1;DAY<=$DAY_NUM;DAY++));

do

    if [[ $DAY -lt 10 ]]; then

        DATE=$YEAR"-"$MONTH"-0"$DAY

        FILE_NAME="'"$FILE_PATH$DATABASE.$TABLE"_"$YEAR$MONTH"0"$DAY".sql'"

    else

        DATE=$YEAR"-"$MONTH"-"$DAY

        FILE_NAME="'"$FILE_PATH$DATABASE.$TABLE"_"$YEAR$MONTH$DAY".sql'"

    fi

    TIME_BEGIN=$DATE" 00:00:00"

    TIME_END=$DATE" 23:59:59"

    OUTFILE=" INTO OUTFILE $FILE_NAME"

    #导出数据

    EXPORT_SQL='SELECT * FROM '"$DATABASE.$TABLE $INDEX WHERE TIME BETWEEN '$TIME_BEGIN' AND '$TIME_END' $OUTFILE"

    RESULT=`$MYSQL -e "$EXPORT_SQL"`

    #导入数据

    LOAD_SQL="LOAD DATA INFILE $FILE_NAME INTO TABLE $DATABASE.$CHILD_TABLE;"

    RESULT=`$MYSQL -e "$LOAD_SQL"`

    echo "$DATE Completed."

    sleep 3s

done

echo "All Done."

上一篇下一篇

猜你喜欢

热点阅读