이전 포스팅은 Master-Slave 구조를 가지는 Database를 도커를 통해서 수동설정하는 방법을 알아보았습니다.
이번 포스팅은 docker-compose를 통해서 한번에 Master-Slave 구조를 가질 수 있도록 DB container를 생성하고, shell script를 통해서 replication할 DB를 생성과 master slave 구조를 가지도록 하겠습니다. (자동화)
git : [https://github.com/YouJaeBeom/DB_Master-Slave_dockercompose]
해당 디렉토리의 구조를 보도록 하겠습니다.
디렉토리의 구성과 각자 용도는 아래와 같습니다.
version: "3.3"
services:
db_master:
image: mariadb:10.6.3-focal
container_name: db_master
restart: always
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
volumes:
- ./master/data:/var/lib/mysql
- ./master/config/:/etc/mysql/conf.d
- ./master/mysql-init-files/:/docker-entrypoint-initdb.d/
ports:
- "33306:3306"
secrets:
- mariadb_root_password
db_slave:
image: mariadb:10.6.3-focal
container_name: db_slave
restart: always
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
volumes:
- ./slave/data:/var/lib/mysql
- ./slave/config/:/etc/mysql/conf.d
- ./slave/mysql-init-files/:/docker-entrypoint-initdb.d/
ports:
- "43306:3306"
secrets:
- mariadb_root_password
depends_on:
- db_master
secrets:
mariadb_root_password:
file: ./mariadb_root_password.txt
services 내에 두개가 존재하는것을 확인 할 수 있습니다.
db_master 가 Master DB 역할을 하는 것이며, db_slave가 Slave DB 역할을 합니다.
각 옵션별로 살펴보면
기본 디렉토리에서 master 로 이동합니다.
그 후 총 2가지의 파일들을 알아보겠습니다.
[mysqld]
log-bin=mysql-bin
server-id=1
위와 같이 Master DB container는 설정해줍니다.
CREATE DATABASE dbname;
##create masteruser and grant privileges
grant all privileges on dbname.* to dbname@'%' identified by 'password';
#replication
grant replication slave on *.* to 'dbname'@'%';
## flushj
flush privileges;
첫번째로는 복제할 데이터베이스를 생성하고, 해당 DB에 권한을 설정합니다.
그 다음 slave에게 replication할 권한을 주고, 저장합니다.
여기서 사용자들은 dbname 이나 password 등만 수정하면 됩니다.
기본 디렉토리에서 slave 로 이동합니다.
그 후 총 2가지의 파일들을 알아보겠습니다.
[mysqld]
log-bin=mysql-bin
server-id=2
relay-log=relaylog
log-slave_updates=1
위와 같이 Slave DB container는 설정해줍니다.
CREATE DATABASE dbname;
#create masteruser and grant privileges
create user dbname@'%' identified by 'password';
grant all privileges on dbname.* to dbname@'%' identified by 'password';
## flush
flush privileges;
여기서 DB를 만드는 이유는 첫 replication하기 위해서 싱크를 맞추기 위함입니다.
한마디로 master에서 설정한 dbname 과 password를 똑같이 써줍니다.
run.sh 이라는 shell script는 이제 모든 과정을 자동화하는 파일입니다.
#!/bin/bash
docker-compose -f ./docker-compose.yml up -d
sleep 5
master_log_file=`mysql -h127.0.0.1 --port 33306 -uroot -ppassword -e "show master status\G" | grep mysql-bin`
master_log_file=${master_log_file}
master_log_file=${master_log_file//[[:blank:]]/}
master_log_file=${${master_log_file}#File:}
echo ${master_log_file}
master_log_pos=`mysql -h127.0.0.1 --port 33306 -uroot -ppassword -e "show master status\G" | grep Position`
master_log_pos=${master_log_pos}
master_log_pos=${master_log_pos//[[:blank:]]/}
master_log_pos=${${master_log_pos}#Position:}
echo ${master_log_pos}
query="CHANGE MASTER TO MASTER_HOST='db_master', MASTER_USER='dbname', MASTER_PASSWORD='rootpassword', MASTER_LOG_FILE='${master_log_file}', MASTER_LOG_POS=${master_log_pos} ,master_port=33306"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "stop slave"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "${query}"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "start slave"
docker-compose.yml 파일을 실행 시켜줌으로서 Master-Slave가 될 DB container를 띄워주게 됩니다.
docker-compose -f ./docker-compose.yml up -d
그 다음은 Master DB container 내에 있는 DB 의 Log_file 값과 Log_position 값을 가져옵니다.
master_log_file=`mysql -h127.0.0.1 --port 33306 -uroot -ppassword -e "show master status\G" | grep mysql-bin`
master_log_file=${master_log_file}
master_log_file=${master_log_file//[[:blank:]]/}
master_log_file=${${master_log_file}#File:}
echo ${master_log_file}
master_log_pos=`mysql -h127.0.0.1 --port 33306 -uroot -ppassword -e "show master status\G" | grep Position`
master_log_pos=${master_log_pos}
master_log_pos=${master_log_pos//[[:blank:]]/}
master_log_pos=${${master_log_pos}#Position:}
echo ${master_log_pos}
그 다음 두개의 값을 slave DB container 내에 있는 DB에게 권한을 줌으로써 완성시키게 됩니다.
query="CHANGE MASTER TO MASTER_HOST='db_master', MASTER_USER='dbname', MASTER_PASSWORD='rootpassword', MASTER_LOG_FILE='${master_log_file}', MASTER_LOG_POS=${master_log_pos} ,master_port=33306"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "stop slave"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "${query}"
mysql -h127.0.0.1 --port 43306 -uroot -psamjung -e "start slave"
실행 명령어는 아래와 같습니다.
source run.sh
실행 후 이제 결과를 확인해봐야합니다.
Slave DB container에 접속하여 DB에 들어가도록 합니다.
## option 1
docker exec -it db_slave /bin/bash
mysql -u root -p
>> rootpassword
## option 2
mysql mysql -h127.0.0.1 --port 43306 -uroot -prootpassword
데이터베이스에 들어온 후 아래와 같은 명령어를 사용합니다.
show slave status\G
사용하게 되면 아래와 같은 화면이 나오게 됩니다.
여기서 우리는 Last_Errno 는 0, Last_IO_Errno가 0이면 설정이 완료된것 입니다.
설정을 완료하게 되면 이제 Master container에서 복제설정한 DB에 데이터가 들어가거나 삭제되는경우 Slave DB에도 바로 적용되는 것을 확인 할 수 있습니다.