MySQL replication bash script.

2020. 3. 23. 00:57참고

 

 

 

사전 작업

 

- 미리 두개의 서버에 이중화할 DB를 생성합니다.

- 이중화에 사용할 MySQL 유저를 생성합니다. ex) master(쓰기전용), slave(읽기전용), repluser(이중화 전용)

- 보안을 위해 MySQL 접속은 키 파일로 변경. (mysql_config_editor)

- RSA private key를 사용하여 원격 서버에 ssh 접속(AWS)할 경우 RSA 키 파일 권한은 600 적용.

 

[참고] 독커 기반 MySQL 리플리케이션

https://jupiny.com/2017/11/07/docker-mysql-replicaiton/

https://teamsmiley.github.io/2018/08/05/docker-mysql-replication/

 

이제 위 내용을 bash 스크립트로 한방에.

(filename : make_mysql_replication)

#!/bin/bash

if [ -z $1 ]
then
        sourceip="your write db(master) server ip"
else
        sourceip=$1
fi

if [ -z $2 ]
then
        remoteip="your read db(slave) server ip"
else
        remoteip=$2
fi

echo "source ip: $sourceip"
echo "remote ip: $remoteip"

if [[ -z $sourceip && -z $remoteip ]]
then
        echo "arg1 : remote ip or 'remote' when remote copied"
elif [ $sourceip = "remote" ]
then
        # recover db
        IFS=' ' read -ra inforepls <<< $(<inforepl);
        echo "${inforepls[0]} ${inforepls[1]} ${inforepls[2]}";
        IFS=' ' read -ra containerids <<< $(docker ps | grep 'mymon');

        echo "${containerids[0]} DROP DATABASE ct";
        docker exec ${containerids[0]} mysql --login-path=slave -e 'DROP DATABASE ct';

        echo "CREATE DATABASE ct";
        docker exec ${containerids[0]} mysql --login-path=slave -e 'CREATE DATABASE IF NOT EXISTS ct';

        echo "RECOVER backup.sql";
        cat backup.sql | docker exec -i ${containerids[0]} mysql --login-path=slave ct;

        echo "STOP SLAVE";
        docker exec ${containerids[0]} mysql --login-path=slave -e 'STOP SLAVE';

        sql="CHANGE MASTER TO master_host='${inforepls[0]}', master_user='repluser', master_password='replpw', master_log_file='${inforepls[1]}', 
master_log_pos=${inforepls[2]}";
        echo $sql;
        docker exec ${containerids[0]} mysql --login-path=slave -e "$sql";

        echo "START SLAVE";
        #docker exec ${containerids[0]} mysql --login-path=slave -e 'RESET SLAVE;START SLAVE;'; 
        docker exec ${containerids[0]} mysql --login-path=slave -e 'START SLAVE;';
else

        # backup sql
        IFS=' ' read -ra containerids <<< "$(docker ps | grep 'mymon')"
        docker exec ${containerids[0]} mysqldump --login-path=master ct > backup.sql
        echo ${containerids[0]}

        # file name
        filename=$(docker exec ${containerids[0]} mysql --login-path=master -e "SHOW MASTER STATUS\G" | grep 'File:')
        filename=${filename##*:}
        echo $filename

        # file position
        position=$(docker exec ${containerids[0]} mysql --login-path=master -e "SHOW MASTER STATUS\G" | grep 'Position:')
        position=${position##*:}
        echo $position

        echo "$sourceip $filename $position"
        echo "$sourceip $filename $position" > inforepl

        echo "send backup.sql to $remoteip"
        scp -i "private.pem" ./backup.sql ubuntu@$remoteip:/home/ubuntu/mysql &
        wait $!

        echo "copy makerepl script to $remoteip"
        scp -i "private.pem" ./makerepl ubuntu@$remoteip:/home/ubuntu/mysql &
        wait $!

        echo "copy inforepl to $remoteip"
        scp -i "private.pem" ./inforepl ubuntu@$remoteip:/home/ubuntu/mysql &
        wait $!

        echo "run remote makerepl 'remote'"
        tempscript="cd mysql;pwd;. ./makerepl remote"
        ssh -i "private.pem" ubuntu@$remoteip $tempscript &
        wait $!
fi

 

동작 설명

쓰기 DB 서버에서 위 스크립트를 실행합니다.

ex) make_mysql_replication src_ip dst_ip

 

쓰기 DB 서버 IP(src_ip)와 읽기 DB 서버 IP(dst_ip)를 입력하면 쓰기 DB를 덤프하여 읽기 DB에 복사하고 MySQL 리플리케이션 설정을 진행합니다.

사고 발생 시 5분 정도 수작업하는 시간을 5초로 단축하는 효과.

물론 DB가 커지면 쓰기 DB 파일을 읽기에덮어 쓰고 갱신하고 적용하는 방식으로 바뀌지 않을까 예상합니다.

 

 

 

참고

 

MySQL 외부 접속 사용자 추가
https://linuxism.ustd.ip.or.kr/33

Docker 기반 위에서 동작하는 MariaDB 백업하기
https://elfinlas.github.io/2018/06/09/docker-mariadb-backup/

How to trim whitespace from a Bash variable
https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable

Bash 문자열 변수 조작 (자르기, 삭제, 치환)
https://www.snoopybox.co.kr/1811

How to Split String in Bash Script.
https://linuxhandbook.com/bash-split-string/

Bash 배열
https://wiki.kldp.org/HOWTO/html/Adv-Bash-Scr-HOWTO/arrays.html

고급 Bash 스크립팅 가이드
https://wiki.kldp.org/HOWTO/html/Adv-Bash-Scr-HOWTO/index.html

MySQL 복원시 덮어쓰기
http://blog.daum.net/_blog/BlogTypeView.do?blogid=0MwDd&articleno=7617621&_bloghome_menu=recenttext

Bash 초보자를 위한 핵심 요약 정리
https://blog.gaerae.com/2015/01/bash-hello-world.html