
사전 준비
MariaDB 이중화, 다중화 순서
마스터 구성
(1) 바이너리 로그 활성화
(2) 마스터에 고유한 server_id 부여
(3) --log-basename
옵션 사용해 복제 로그에 고유 이름 지정
(4) 로그 포맷 지정
슬레이브 구성
(1) 슬레이브에 고유한 server_id 부여
파일 구성
1
2
3
4
| MARIADB_ROOT_PASSWORD=mariadbpasswd
MARIADB1_PORT=19000
MARIADB2_PORT=19001
MARIADB3_PORT=19002
|
- docker-compose 파일 (
docker-compose.yml
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| services:
mariadb_1:
# master
image: mariadb:11.8.1-rc
container_name: mariadb_1
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
ports:
- "${MARIADB1_PORT}:3306"
volumes:
- ./mariadb1/data:/var/lib/mysql
- ./mariadb1/conf.d:/etc/mysql/conf.d
- ./mariadb1/backup:/backup
mariadb_2:
# slave
image: mariadb:11.8.1-rc
container_name: mariadb_2
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
ports:
- "${MARIADB2_PORT}:3306"
volumes:
- ./mariadb2/data:/var/lib/mysql
- ./mariadb2/conf.d:/etc/mysql/conf.d
- ./mariadb2/backup:/backup
mariadb_3:
# master
image: mariadb:11.8.1-rc
container_name: mariadb_3
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
ports:
- "${MARIADB3_PORT}:3306"
volumes:
- ./mariadb3/data:/var/lib/mysql
- ./mariadb3/conf.d:/etc/mysql/conf.d
- ./mariadb3/backup:/backup
|
MariaDB 들 실행 (Docker-Compose)
1
| sudo docker compose up -d
|
마스터 구성
마스터 DB 설정 수정
mariadb1/conf.d
디렉터리에 커스텀 설정파일을 만듭니다.
- 바이너리 로그 활성화
- server_id 지정
- 로그 베이스네임 지정
- 로그 포맷 지정
- 접근 가능 호스트 지정 (선택사항)
1
| vi mariadb1/conf.d/custom.cnf
|
1
2
3
4
5
6
| [mysqld]
log-bin
server_id=1
log-basename=master1
binlog-format=mixed
bind-address=0.0.0.0
|
MariaDB 재시작
- 설정 적용을 위해 MariaDB 를 재시작해줍니다.
1
| sudo docker restart mariadb_1
|
복제 전용 유저 생성
- 마스터 MariaDB 에 root 계정으로 접속합니다.
- 그리고 복제 전용 유저를 생성해주겠습니다.
1
| docker exec -it mariadb mariadb -uroot
|
1
2
| CREATE USER 'replication_user'@'%' IDENTIFIED BY 'bigs3cret';
GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%';
|
설정 체크
- 아래 두 가지 옵션은 원격지의 마스터-슬레이브에 장애가 됩니다.
- 원격지 간 마스터-슬레이브 구축이 필요하다면 아래 두 옵션에 대한 조치를 진행하세요.
skip-networking=1
: 로컬 호스트로만 연결 가능. 모든 원격 슬레이브의 연결을 차단.
bind-address
: TCP/IP 연결을 수신(허용)하는 주소.
skip-networking
- 마리아DB 설정파일들에서
skip-networking
옵션을 제거하거나 주석처리 합니다.
- 기본적으로 skip-networking 은 비활성화 되어있습니다.
bind-address
- bind-address 옵션을 사용한 곳이 있다면 원격지 서버가 접근 가능하도록 추가합니다.
- bind-address 옵션을 사용한 곳이 없다면, 아래와 같이 추가해줍니다.
1
| vi mariadb1/conf.d/custom.cnf
|
1
2
3
| [mysqld]
...
bind-address=0.0.0.0
|
슬레이브 구성
슬레이브 DB 설정 수정
mariadb2/conf.d
디렉터리에 커스텀 설정파일을 만듭니다.
- server_id 지정
1
| vi mariadb2/conf.d/custom.cnf
|
1
2
3
| [mysqld]
server_id=2
bind-address=0.0.0.0
|
MariaDB 재시작
1
| sudo docker restart mariadb_2
|
마스터의 바이너리 로그 위치 얻기
- 본 작업이 진행되는 동안에는 데이터가 변경되지 않아야 합니다.
- 그래야 슬레이브에게 복제 시작의 정확한 시점을 알려줄 수 있기 때문입니다.
- 따라서 본 작업 실행 전 마스터에서 모든 테이블을 플러시하고 잠금을 수행합니다.
1
| sudo docker exec -it mariadb_1 mariadb -uroot
|
1
| FLUSH TABLES WITH READ LOCK;
|
- 다음으로 마스터의 바이너리 로그 위치를 확인합니다.
1
2
3
4
5
6
7
8
| SHOW MASTER STATUS;
>> +--------------------+----------+--------------+------------------+
>> | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
>> +--------------------+----------+--------------+------------------+
>> | master1-bin.000001 | 672 | | |
>> +--------------------+----------+--------------+------------------+
|
기존 데이터 가져오기
- 만약 마스터에 이미 데이터가 있다면, 완벽한 복제를 위해 데이터 가져오기를 실행합니다.
- 자세한 내용은 아래 DOC 참고하시기 바랍니다.
- MariaDB - 데이터 가져오기
슬레이브 데이터베이스 시작
- 슬레이브 데이터베이스에 접속하여, 마스터 데이터베이스를 지정해줍니다.
- 설정파일로 설정은 안되고, 반드시 명령어로 수행해야 합니다.
1
| sudo docker exec -it mariadb_2 mariadb -uroot
|
1
2
3
4
5
6
7
8
9
10
| CHANGE MASTER TO
MASTER_HOST='master.domain.com', // master DB 의 IP 나 주소 입력
MASTER_USER='replication_user', // master DB 의 복제 전용 유저이름
MASTER_PASSWORD='bigs3cret', // 위 유저의 비밀번호
MASTER_PORT=19000, // master DB 의 서비스 포트
MASTER_LOG_FILE='master1-bin.000096', // master DB 바이너리 로그 위치
MASTER_LOG_POS=568, // master DB 바이너리 로그 POS
MASTER_CONNECT_RETRY=10; // master DB 연결 시도 횟수
>> Query OK, 0 rows affected, 1 warning (0.265 sec)
|
마스터 잠금 해제
1
| sudo docker exec -it mariadb_1 mariadb -uroot
|
마스터 슬레이브 테스트
테스트용 계정 생성
- 테스트를 위해 마스터에 사용자 계정을 만들었습니다.
1
| sudo docker exec -it mariadb_1 mariadb -uroot
|
1
2
3
| CREATE USER 'test_user'@'%' IDENTIFIED BY 'strongpasswd';
GRANT ALL PRIVILEGES ON *.* TO 'test_user'@'%';
FLUSH PRIVILEGES;
|
접속 테스트
1
2
3
4
5
6
| sudo docker exec -it mariadb_1 mariadb -utest_user -p
# strongpasswd
>> Your MariaDB connection id is 26
>> ...
>> MariaDB [(none)]>
|
1
2
3
4
5
6
| sudo docker exec -it mariadb_2 mariadb -utest_user -p
# strongpasswd
>> Your MariaDB connection id is 26
>> ...
>> MariaDB [(none)]>
|
- 슬레이브엔 계정을 명시적으로 만들어주지 않았었습니다.
- 하지만, 마스터의 로그를 가져와 슬레이브에서도 계정 생성이 수행되어 있습니다.
테이블 생성
- 마스터에서 DB 및 테이블을 생성하고, 몇 가지 데이터를 넣어보겠습니다.
1
| sudo docker exec -it mariadb_1 mariadb -utest_user -p
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| -- DB 생성 및 선택
CREATE DATABASE TEST_DB;
USE TEST_DB;
-- 테이블 생성
CREATE TABLE TEST_TABLE (
ID INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(10),
INPUT_DT TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 데이터 입력
INSERT INTO TEST_TABLE (NAME) VALUE ('김마스터');
INSERT INTO TEST_TABLE (NAME) VALUE ('김슬레이브');
|
1
2
3
4
5
6
7
8
9
| -- 입력 데이터 확인
SELECT * FROM TEST_TABLE;
>> +----+-----------------+---------------------+
>> | ID | NAME | INPUT_DT |
>> +----+-----------------+---------------------+
>> | 1 | 김마스터 | 2025-06-10 06:32:13 |
>> | 2 | 김슬레이브 | 2025-06-10 06:32:18 |
>> +----+-----------------+---------------------+
|
슬레이브 조회
- 슬레이브에서 테이블이 잘 복제되었는지 확인합니다.
1
| sudo docker exec -it mariadb_2 mariadb -utest_user -p
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| -- DB부터 확인
SHOW DATABASES;
>> +--------------------+
>> | Database |
>> +--------------------+
>> | TEST_DB |
>> ...
>> +--------------------+
-- 테이블 및 내용 확인
USE TEST_DB;
SHOW TABLES;
>> +-------------------+
>> | Tables_in_TEST_DB |
>> +-------------------+
>> | TEST_TABLE |
>> +-------------------+
-- 테이블에서 데이터 조회
SELECT * FROM TEST_TABLE;
>> +----+-----------------+---------------------+
>> | ID | NAME | INPUT_DT |
>> +----+-----------------+---------------------+
>> | 1 | 김마스터 | 2025-06-10 06:32:13 |
>> | 2 | 김슬레이브 | 2025-06-10 06:32:18 |
>> +----+-----------------+---------------------+
|
실험
슬레이브에서 데이터를 삽입하면?
1
2
3
4
5
6
7
8
9
10
11
12
| -- 데이터 삽입
INSERT INTO TEST_TABLE (NAME) VALUE ('슬레이브삽입');
-- 데이터 조회
SELECT * FROM TEST_TABLE;
>> +----+--------------------+---------------------+
>> | ID | NAME | INPUT_DT |
>> +----+--------------------+---------------------+
>> | 1 | 김마스터 | 2025-06-10 06:32:13 |
>> | 2 | 김슬레이브 | 2025-06-10 06:32:18 |
>> | 3 | 슬레이브삽입 | 2025-06-10 06:37:03 |
>> +----+--------------------+---------------------+
|
- 마스터에서 확인해보면 슬레이브에서 삽입한 데이터는 들어와있지 않다.
- 이렇게 되면 이중화/다중화가 깨지는 것이므로, 슬레이브에 삽입하지 않게 주의!
1
| sudo docker exec -it mariadb_1 mariadb -utest_user -p
|
1
2
3
4
5
6
7
8
| SELECT * FROM TEST_TABLE;
>> +----+-----------------+---------------------+
>> | ID | NAME | INPUT_DT |
>> +----+-----------------+---------------------+
>> | 1 | 김마스터 | 2025-06-10 06:32:13 |
>> | 2 | 김슬레이브 | 2025-06-10 06:32:18 |
>> +----+-----------------+---------------------+
|
참고
- 마스터-슬레이브 구조 뿐만 아니라, 마스터-마스터 구조 또한 가능하다.
- 하지만 마스터-마스터는 데이터 충돌의 가능성, 복잡한 관리 때문에 피하는 게 권장된다.
- 마스터-마스터 구조가 필요할 경우, 직접적인 연결보다는 메시지 큐나 로그 브로커를 이용한 비동기 이벤트 전파 방식이 더 안정적이고 확장성도 좋아 권장된다.
- full 백업도 있다. 참고 - MariaDB-backup
- 이번 마스터-슬레이브 구조 구축을 통해 장애발생에 따른 대응, 읽기 부하 분산을 얻을 수 있다.
Reference
MariaDB - Setting Up Replication
MariaDB - CHANGE MASTER TO
MariaDB - Option - skip networking
MariaDB - binary log
MariaDB - log option - log-basename
Comments