docker-compose에서 mysql 컨테이너를 세우고 replication을 적용 (mac)

DB 복제란?




Master DB의 데이터는 Slave DB와 동기화되어 Slave DB에서 동일한 데이터를 확인할 수 있습니다.
데이터의 안정성을 확보하고 쓰기는 Master DB, 읽기는 Slave DB를 이용하여 DB의 부하를 낮추는 데 사용합니다.
(최근에는 Master나 Slave등의 말은 사용하지 않는 방향으로 진행되고 있습니다만)

디렉토리 구조





docker-compose.yml



docker-compose.yml
version: '3.3'

services:
  db-master:
    image: mymaster
    volumes:
      - ./mymaster/mysql-init-files/:/docker-entrypoint-initdb.d/
      - ./mymaster/mysql-config-files/:/etc/mysql/conf.d
    restart: always
    container_name: mymaster
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD="true"
    ports:
      - '3333:3306'
    expose:
      - '3333'

  db-slave:
    image: myslave
    volumes:
      - ./myslave/mysql-init-files/:/docker-entrypoint-initdb.d/
      - ./myslave/mysql-config-files/:/etc/mysql/conf.d
    restart: always
    container_name: myslave
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD="true"
    ports:
      - '2222:3306'
    expose:
      - '2222'

image로서 mymaster를 이용하고 있습니다만, dockerfile로 빌드한 것입니다. 큰 내용은 없기 때문에 mysql의 image를 사용해도 괜찮습니다.

Master 설정



dockerfile



dockerfile
FROM mysql:5.7

EXPOSE 3306

CMD ["mysqld"]

my.cnf


[mysqld]
log-bin=mysql-bin
server-id=1

log-bin은 쿼리를 실행할 때 남기는 로그입니다.
server-id를 1로 지정합니다.

create.sql



create.sql
CREATE DATABASE repl;

CREATE TABLE repl.user(
  id VARCHAR(100) PRIMARY KEY,
  name VARCHAR (100)
);

create user master@'%' identified by 'master';
grant all privileges on *.* to master@'%' identified by 'master';

grant replication slave on *.* to 'slave'@'%' identified by 'slave';

중요한 것은grant replication slave on *.* to 'slave'@'%' identified by 'slave';에서 슬레이브에서 복제하는 사용자를 만드는 것입니다.

슬레이브 설정



dockerfile



dockerfile
FROM mysql:5.7

EXPOSE 3306

CMD ["mysqld"]

Master와 동일합니다.

my.cnf


[mysqld]
server-id=2
replicate-do-db='repl'

server-id를 2로 지정합니다.
복제할 DB를 지정합니다.

create.sql



create.sql
CREATE DATABASE repl;

CREATE TABLE repl.user(
  id VARCHAR(100) PRIMARY KEY,
  name VARCHAR (100)
);

create user slave@'%' identified by 'slave';
grant all privileges on repl.* to slave@'%' identified by 'slave';

복제를 위해 마스터와 동일한 테이블을 작성해야 합니다.

마지막으로 쉘 스크립트에서 복제를 수행합니다.

복제 실행



오, t. sh



init.sh
#!/bin/sh

#make mymaster image
docker build --no-cache -t mymaster ./mymaster/

#make myslave image
docker build --no-cache -t myslave ./myslave/
docker-compose -f ./docker-compose.yml up -d --remove-orphans

sleep 15s

# macのコマンドですので、Windowsなら他のIPアドレス取得方法が必要です。
myaddress=`ipconfig getifaddr en0`
myaddress=${myaddress}

# Masterのログファイルの場所を取得します。
master_log_file=`mysql -h127.0.0.1 --port 3333 -uroot -e "show master status\G" | grep mysql-bin`
master_log_file="${master_log_file}"

re="[a-z]*-bin.[0-9]*"

if [[ ${master_log_file} =~ $re ]];then
    master_log_file=${BASH_REMATCH[0]}
fi

# Masterのポジションも取得します。
master_log_pos=`mysql -h127.0.0.1 --port 3333 -uroot -e "show master status\G" | grep Position`
master_log_pos="${master_log_pos}"

re="[0-9]+"

if [[ ${master_log_pos} =~ $re ]];then
    master_log_pos=${BASH_REMATCH[0]}
fi

query="change master to master_host='${myaddress}', master_user='slave', master_password='slave', master_log_file='${master_log_file}', master_log_pos=${master_log_pos}, master_port=3333"

mysql -h127.0.0.1 --port 2222 -uroot -e "${query}"
mysql -h127.0.0.1 --port 2222 -uroot -e "start slave"

init.sh를 실행하면 docker image를 빌드하고 컨테이너간에 복제를 수행합니다.
이제 복제를 한 mysql 컨테이너를 만들었습니다.

좋은 웹페이지 즐겨찾기