개발/환경구성

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

onethejay 2023. 3. 15. 22:39
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