Reminiscence

 

multidump.zip

 

제목은 거창한데.. 내용은 별거 없네요.. ^^;

우리 회사에서 운영중인 특정 시스템의 경우 하나의 MySQL DB 서버에 약 2천여개의 DB를 가지고 있습니다.

뭐.. 용량은 서버마다 각각 다르지만, 대략 300GB ~ 500GB 사이를 왔다갔다 하는 서버죠

그런데 이 DB 엔진이 MyISAM으로 되어 있고, 이걸 InnoDB로 변경하면서 서버 교체까지 한번에 진행해야 하는 문제가 생깁니다.

이에 mysqldump로 힘들게 덤프 떠보니 속도가 너무 꽝이네요 .. -ㅠ - ;;

그래서 만들었습니다. 멀티쓰레드 덤프 ㅡ.,ㅡ;;

 

내용은 별거 없고 기본적인 흐름은 다음과 같습니다.

1. 현재 DB 서버 내 전체 데이터베이스 목록을 파일로 만든다.

2. 각 데이터베이스 이름마다 child process를 생성한다.

3. 각 child process에서 백업 작업이 끝나면, 목록에서 자신의 DB 명을 지우고 종료 한다.

 

간단한 스크립트라 공개하기에도 민망한데 필요하신 분들이 혹(?) 계실지도 모르니.. ^^;

 

###############

## multidump.sh  #

###############

## 4core MULTIDUMP SCRIPT

#!/bin/bash

 

remove_list() {

        sed -e "/^${DBNAME}$/d" $DB_LIST_FILE >> TMPFILE1;

        rm -f $DB_LIST_FILE;

        mv TMPFILE1 $DB_LIST_FILE;

echo "$DBNAME" >> RESTORE_LIST;

}

 

export c_black='\033[0m'

export c_boldblack='\033[1;0m'

export c_red='\033[31m'

export c_boldred='\033[1;31m'

export c_green='\033[32m'

export c_boldgreen='\033[1;32m'

export c_yellow='\033[33m'

export c_boldyellow='\033[1;33m'

export c_blue='\033[34m'

export c_boldblue='\033[1;34m'

export c_magenta='\033[35m'

export c_boldmagenta='\033[1;35m'

export c_cyan='\033[36m'

export c_boldcyan='\033[1;36m'

export c_white='\033[37m'

export c_boldwhite='\033[1;37m'

export c_colorend='\033[0m'

 

cecho ()

{

        local default_msg="No Message Passed."

 

        message=${1:-$default_msg}

        color=${2:-black}

 

        case $color in

                black)

                         printf "$c_black" ;;

                boldblack)

                         printf "$c_boldblack" ;;

                green)

                         printf "$c_green" ;;

                boldgreen)

                         printf "$c_boldgreen" ;;

                red)

                         printf "$c_red" ;;

                boldred)

                         printf "$c_boldred" ;;

                yellow)

                         printf "$c_yellow" ;;

                boldyellow)

                         printf "$c_boldyellow" ;;

                blue)

                         printf "$c_blue" ;;

                boldblue)

                         printf "$c_boldblue" ;;

                magenta)

                         printf "$c_magenta" ;;

                boldmagenta)

                         printf "$c_boldmagenta" ;;

                cyan)

                         printf "$c_cyan" ;;

                boldcyan)

                         printf "$c_boldcyan" ;;

                white)

                         printf "$c_white" ;;

                boldwhite)

                        printf "$c_boldwhite" ;;

        esac

        printf "%s$c_colorend\n" "$message"

}

 

dump_list(){

 

DISABLE_DB_LIST="information_schema mysql performance_schema sysbench test vsftp webmail webmail_admin wordlist";

 

mysql -h $DUMP_HOST -Ne "show databases" >> db_list;

for INF in $DISABLE_DB_LIST;do

        sed -e "/^${INF}$/d" db_list >> tmp_list

        rm -f db_list;

        mv tmp_list db_list;

done;

 

}

 

# 임시 파일 생성

cecho "==== Temporary file create ====" boldgreen

echo "1" >> PROC_TMP1;

echo "1" >> PROC_TMP2;

echo "1" >> PROC_TMP3;

echo "1" >> PROC_TMP4;

 

CNT="0"

DB_LIST_FILE="./db_list"

CHILD_BIN="./multidump_child.sh"

DUMP_HOST="192.168.1.15"

S_DATE=`date +"%Y-%m-%d %H:%M:%S"`

 

# DB LIST OUTPUT

cecho "==== START TIME : ${S_DATE} ====" boldgreen

cecho "==== Backup target listing ====" boldgreen

dump_list;

TOTAL_RUN=`cat $DB_LIST_FILE | wc -l`

sleep 1;

 

 

while (( `cat $DB_LIST_FILE | wc -l` ))

do

        sleep 1;

 

        DBNAME=`tail -n 1 $DB_LIST_FILE`;

 

        if [ -s PROC_TMP1 ]

        then

                cat /dev/null > PROC_TMP1;

                CNT=`expr $CNT + 1`

                cecho "  * ($CNT/$TOTAL_RUN) : $DBNAME DUMP 실행 " boldblue

                $CHILD_BIN $DBNAME PROC_TMP1 $DUMP_HOST &

                remove_list

        elif [ -s PROC_TMP2 ]

        then

                cat /dev/null > PROC_TMP2;

                CNT=`expr $CNT + 1`

                cecho "  * ($CNT/$TOTAL_RUN) : $DBNAME DUMP 실행 " boldblue

                $CHILD_BIN $DBNAME PROC_TMP2 $DUMP_HOST &

                remove_list

        elif [ -s PROC_TMP3 ]

        then

                cat /dev/null > PROC_TMP3;

                CNT=`expr $CNT + 1`

                cecho "  * ($CNT/$TOTAL_RUN) : $DBNAME DUMP 실행 " boldblue

                $CHILD_BIN $DBNAME PROC_TMP3 $DUMP_HOST &

                remove_list

        elif [ -s PROC_TMP4 ]

        then

                cat /dev/null > PROC_TMP4;

                CNT=`expr $CNT + 1`

                cecho "  * ($CNT/$TOTAL_RUN) : $DBNAME DUMP 실행 " boldblue

                $CHILD_BIN $DBNAME PROC_TMP4 $DUMP_HOST &

                remove_list

        else

                cecho "==== 현재 모든 프로세스가 처리 중입니다. ====" boldwhite

        fi

done

 

rm -f PROC_TMP*;

 

cecho "==== START TIME : ${S_DATE} ====" boldgreen

S_DATE=`date +"%Y-%m-%d %H:%M:%S"`

cecho "==== END TIME : ${S_DATE} ====" boldgreen

 

여기까지가 메인 스크립트이구요.. 아래는 multidump_child.sh 스크립트 입니다.

####################

## multidump_child.sh ##

####################

## MULTIDUMP CHILD SCRIPT

## Dump 하면서 sed를 이용해 백업되는 데이터의 Engine Type을 InnoDB로 변경한다.

 

#!/bin/bash

/usr/local/mysql/bin/mysqldump -h $3 --force -c $1 | sed "s/ENGINE=MyISAM/ENGINE=InnoDB/g" >> /backup/MULTI_DUMP/${1}_dump.sql

echo "$1" >> $2;

 

지금도 가끔 쓰는 스크립트지만, 그때 그때 수정해서 필요한 부분에 맞게 맞춰서 쓰고 있구요..

그냥 mysqldump로 뜨는것보단 한 2배에서 2.5배 정도 빠르네요..

Sed로 치환처리 안하면 좀 더 빠릅니다. ;;

 

위에는 4개 스레드를 기본으로 한건데 8개로 하면 쪼~~~~끔 더 빨라지니.. 필요에 따라.. =_=;;;

저작자 표시
신고

댓글 0개가 달렸습니다.