본문 바로가기
개발/개발환경

[docker] MariaDB Master - Slave Replication (복제, 이중화) 구성

by onethejay 2023. 3. 15.
728x90

서비스 프로젝트를 구성하면서 DB를 이중화해서 관리하면 좋겠다는 생각이 들어 정리하게 되었습니다.

OS는 Windows이며 Docker 환경에서 작업합니다.

먼저 Master와 Slave로 사용할 Mariadb 도커가 필요하므로 구분해서 생성합니다. (mariadb-master, mariadb-slave)

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -e TZ=Asia/Seoul --name mariadb-master mariadb --lower_case_table_names=1
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=password -e TZ=Asia/Seoul --name mariadb-slave mariadb --lower_case_table_names=1

docker-compose를 사용하면 아래처럼 구성할수도 있습니다.

version: '3.7'
services:
  mariadb1:
    container_name: mariadb-master
    image: mariadb
    ports:
      - "3306:3306"
    command: --lower_case_table_names=1    
    environment:
      MYSQL_ROOT_PASSWORD: password
      TZ: Asia/Seoul

  mariadb2:
    container_name: mariadb-slave
    image: mariadb
    ports:
      - "3308:3306"
    command: --lower_case_table_names=1    
    environment:
      MYSQL_ROOT_PASSWORD: password
      TZ: Asia/Seoul

위에서의 run 명령어로 컨테이너 부팅까지 완료되어 있을 것입니다.

Master DB

그럼 이제 Master DB부터 세팅을 시작합니다.

도커 컨테이너로 접속합니다.

docker exec -it mariadb-master /bin/bash

mariadb의 설정파일을 수정하려면 vi 에디터가 필요합니다.
현재 컨테이너에는 설치가 되어있지 않으니 먼저 설치하도록 합니다.

apt update; apt install vim;

설치가 완료되었다면 /etc/mysql/my.cnf 파일을 수정합니다.

vi /etc/mysql/my.cnf

영어 I(아이)를 누르면 INSERT 상태가 되고 cmd에서는 오른쪽 클릭하면 복사한 내용을 붙여넣을 수 있습니다.

아래 내용을 파일의 맨 아래에 추가합니다.

[mysqld]

log-bin = mysql-bin 
server-id = 1 
binlog_format = row 
expire_logs_days = 2

작성 혹은 붙여넣기가 완료되었다면 esc를 누른 상태에서 :wq! 를 입력 (콜론 + w + q + 느낌표) 한 후 엔터를 누릅니다.

exit를 입력해서 컨테이너에서 빠져 나온 후 컨테이너를 재시작해줍니다.

docker restart mariadb-master

재시작이 완료되었다면 다시 컨테이너에 접속합니다.

docker exec -it mariadb-master /bin/bash

Slave DB에서 Master DB로 접근 가능한 계정을 생성하기 위해 mysql에 접속합니다.

mysql -u root -p

비밀번호는 위에서 지정했던 password를 입력합니다. (보안으로 인해 입력된 값이 표시되지 않습니다.)


위 화면처럼 접속되었다면 아래 명령어를 입력하여 Slave에서 Master로 연결하기 위한 계정을 생성합니다.

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

Query OK가 표시되었다면 이어서 아래 명령어를 입력합니다.

show master status;

File과 Position에 표시된 값은 Slave DB에서 필요하므로 따로 메모해두시거나,
CMD 창을 닫지 마시고 그대로 두도록 합니다.

Slave DB

이어서 Slave DB를 작업합니다.

컨테이너에 접속합니다.

docker exec -it mariadb-slave /bin/bash

Master와 동일하게 vim을 설치해줍니다.

apt update; apt install vim -y;

설치가 완료되면 Slave도 my.cnf를 에디터로 열어줍니다.

vi /etc/mysql/my.cnf

아래 내용을 파일의 가장 마지막에 붙여넣습니다.
내용은 거의 동일하나 server-id가 2입니다. Master는 1, Slave는 2 입니다.

[mysqld]

log-bin = mysql-bin
server-id = 2
binlog_format = row
expire_logs_days = 2

read_only = 1

저장(esc 후 :wq!)하고 나옵니다. 이후 Slave 컨테이너도 재시작합니다.

docker restart mariadb-slave

재시작이 완료되었으면 다시 접속합니다.

docker exec -it mariadb-slave /bin/bash

이어서 mysql에 접속합니다. (비밀번호는 위에서 지정했던 password)

mysql -u root -p

아래 쿼리를 입력합니다.

CHANGE MASTER TO MASTER_HOST = '192.168.1.19'
    , MASTER_PORT=3306
    , MASTER_USER='repl_user'
    , MASTER_PASSWORD='p@ssw0rd'
    , MASTER_LOG_FILE='mysql-bin.000001'  
    , MASTER_LOG_POS=523
    , MASTER_CONNECT_RETRY=10;
  • MASTER_HOST에 Docker를 사용중이라면 Host PC의 IP를 입력해야 합니다. (ipconfig)
  • MASTER_PORT는 Master DB의 접속 가능한 포트를 입력합니다.
  • MASTER_USER, MASTER_PASSWORD는 위에서 생성한 Slave DB에서 Master DB로 접근이 가능한 계정 정보를 입력합니다.
  • MASTER_LOG_FILE, MASTER_LOG_POS 위에서 말했던 접속 정보 생성시 필요한 내용을 적어줍니다.

slave db를 시작합니다.

start slave;

정상적으로 연결되었는지 확인하기 위해 쿼리를 실행합니다.

show slave status;

Slave_IO_Running과 Slave_SQL_Running이 둘다 Yes 가 되어있다면 성공한것입니다.
위 사진처럼 되어있어서 보기 힘들다면, HeidiSQL이나 Mysql Workbench 같은 db 툴을 이용해 Slave DB에 접속하여 쿼리를 실행하면 됩니다.

만약 start slave 를 입력했을때 Could not initialize master info structure for ''; 에러가 나타난다면 reset slave를 입력하고 다시 start slave를 입력해보세요.

Replication(복제) 확인

이제 Slave DB가 Master DB의 데이터를 잘 복제 해오는지 확인해보겠습니다.

Master DB 컨테이너에서 mysql에 접속한 후 database를 생성합니다.
(이전에 종료하지 않았다면 바로 작업이 가능합니다.)

docker exec -it mariadb-master /bin/bash
mysql -u root -p
create database sample;

이어서 샘플 테이블을 생성하고 값을 insert합니다.

use sample;

CREATE TABLE tb_test (
    idx INT(11) NULL DEFAULT NULL
)
    COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;

insert into tb_test value (1);

데이터가 잘 추가되었는지 확인합니다.

select * from tb_test;

Slave DB에도 동일하게 보이는지 확인해 봅니다.

docker exec -it mariadb-slave /bin/bash
mysql -u root -p
show databases;

Slave DB에서는 생성하지 않은 sample Database가 출력됩니다. 이어서 테이블도 확인해보겠습니다.

show tables;

Master DB에서 생성한 tb_test가 있습니다. 데이터도 조회해봅니다.

select * from tb_test;

Master의 데이터가 Slave에도 동일하게 복제되었습니다.

참고

https://danidani-de.tistory.com/28
https://whitekeyboard.tistory.com/657

728x90

댓글