TokyoAJ

도쿄아재

SERVER 2025.03.31

Docker로 MariaDB Master-Slave 복제 구성하기 (재시작 시 데이터 유지 포함)

목표

- MariaDB Master / Slave 구성

- 두 DB 간 데이터 복제

- Docker 재시작 시에도 데이터 보존

- 복제 연결 자동화


폴더구조

mariadb-replication/
├── master/
│ ├── Dockerfile
│ ├── my.cnf
│ └── init.sql
├── slave/
│ ├── Dockerfile
│ ├── my.cnf
│ └── init.sql
└── docker-compose.yml


docker-compose.yml

version: '3.8'

version: '3.8' # Docker Compose 파일 형식 버전 (3.8은 최신 버전 중 하나)

services: # 컨테이너 서비스 정의 시작
mariadb-master: # 마스터 데이터베이스 서비스 이름
build: ./master # 마스터 DB의 Dockerfile이 있는 디렉토리 경로
container_name: mariadb-master # 컨테이너 이름 지정
ports: # 포트 매핑 (호스트:컨테이너)
- "13307:3306" # 호스트의 13307 포트를 컨테이너의 3306 포트에 연결
volumes: # 볼륨 마운트 설정
- master-data:/var/lib/mysql # 영구 데이터 저장을 위한 named volume
- ./master/my.cnf:/etc/mysql/my.cnf # 설정 파일 마운트 (호스트의 설정 파일을 컨테이너 내부로)
environment: # 환경 변수 설정
MYSQL_ROOT_PASSWORD: P@ssword # MariaDB root 비밀번호
MYSQL_DATABASE: devdb # 자동 생성할 데이터베이스 이름
MYSQL_USER: user # 생성할 일반 사용자 이름
MYSQL_PASSWORD: pass # 일반 사용자 비밀번호
restart: always # 컨테이너가 중지되면 항상 재시작
networks: # 네트워크 설정
dock_net: # 사용할 네트워크 이름
ipv4_address: 172.16.0.10 # 고정 IP 주소 할당

mariadb-slave: # 슬레이브 데이터베이스 서비스 이름
build: ./slave # 슬레이브 DB의 Dockerfile이 있는 디렉토리 경로
container_name: mariadb-slave # 컨테이너 이름 지정
ports: # 포트 매핑 (호스트:컨테이너)
- "13308:3306" # 호스트의 13308 포트를 컨테이너의 3306 포트에 연결
depends_on: # 서비스 의존성 설정
- mariadb-master # 마스터 서비스가 먼저 실행된 후에 이 서비스가 시작됨
volumes: # 볼륨 마운트 설정
- slave-data:/var/lib/mysql # 영구 데이터 저장을 위한 named volume
- ./slave/my.cnf:/etc/mysql/my.cnf # 설정 파일 마운트 (호스트의 설정 파일을 컨테이너 내부로)
environment: # 환경 변수 설정
MYSQL_ROOT_PASSWORD: P@ssword # MariaDB root 비밀번호
MYSQL_DATABASE: devdb # 자동 생성할 데이터베이스 이름
MYSQL_USER: user # 생성할 일반 사용자 이름
MYSQL_PASSWORD: pass # 일반 사용자 비밀번호
restart: always # 컨테이너가 중지되면 항상 재시작
networks: # 네트워크 설정
dock_net: # 사용할 네트워크 이름
ipv4_address: 172.16.0.11 # 고정 IP 주소 할당

volumes: # 볼륨 정의 섹션
master-data: # 마스터 DB를 위한 영구 볼륨
slave-data: # 슬레이브 DB를 위한 영구 볼륨

networks: # 네트워크 정의 섹션
dock_net: # 네트워크 이름
driver: bridge # 네트워크 드라이버 타입 (bridge는 기본 네트워크 모드)
ipam: # IP 주소 관리 설정
config:
- subnet: 172.16.0.0/16 # 서브넷 마스크 설정 (172.16.x.x 대역 사용)


실행

docker-compose up -d

이미지 생성확인


컨테이너 생성/실행확인


Master 설정

master/my.cnf

[mysqld]
server-id=1
log-bin=mysql-bin
binlog-do-db=devdb


master/init.sql

CREATE USER 'repl'@'%' IDENTIFIED BY 'replpass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;


master/Dockerfile

FROM mariadb:10.11
COPY my.cnf /etc/mysql/conf.d/my.cnf
COPY init.sql /docker-entrypoint-initdb.d/


Slave 설정

slave/my.cnf

[mysqld]
server-id=2
relay-log=relay-log
log-bin=mysql-bin
binlog-do-db=devdb


slave/init.sql

-- 초기화 스크립트가 필요 없다면 빈 파일로 두세요


복제 연결 설정 (slave에서)

Master 컨테이너가 실행되고 SHOW MASTER STATUSG; 명령으로 FilePosition 값확인.

MariaDB [(none)]> SHOW MASTER STATUSG;
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 328
Binlog_Do_DB: devdb
Binlog_Ignore_DB:
1 row in set (0.000 sec)

slave에서 아래 명령 실행:

CHANGE MASTER TO
MASTER_HOST='mariadb-master',
MASTER_USER='repl',
MASTER_PASSWORD='replpass',
MASTER_LOG_FILE='mysql-bin.000002', -- 위에서 확인한 값
MASTER_LOG_POS= 328; -- 위에서 확인한 값

START SLAVE;


복제확인

SHOW SLAVE STATUSG;

MariaDB [(none)]> SHOW SLAVE STATUSG;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: mariadb-master
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 328
Relay_Log_File: relay-log.000004
Relay_Log_Pos: 627
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 328
Relay_Log_Space: 1229
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: optimistic
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 0
Replicate_Rewrite_DB:
1 row in set (0.000 sec)

댓글