본문 바로가기
프로그래밍

MariaDB HA 이중화 구성 (MaxScale , Docker 사용)

by 대도루피 2025. 4. 16.
반응형

MariaDB 이중화 관련 자료가 많지만 따라해서 되는 게 하나도 없음을 알고, 시행착오를 거친 후 다시 구성할 수 있도록 정리해봅니다.

참고로 docker compose 를 사용해서 간편하게 구성할 수 있도록 했으며, Rocky 8.10 서버 에서 테스트했습니다.

 

MariaDB는 11.7.2 버전

MaxScale는 2025년 9월에 GPL로 전환되는 22.08 버전 을 사용했습니다.

GPL 전환이후에는 모든기능을 자유롭게 사용가능합니다. 노드수 제한도 없고요. 그 전까지는 2 노드만.

 

docker-compose.yml

version: '3.8'

services:
  maria1:
    image: mariadb:11.7.2
    container_name: maria1
    environment:
      MYSQL_ROOT_PASSWORD: passwd
    ports:
      - "3307:3306"
    volumes:
      - ./init/node1.sql:/docker-entrypoint-initdb.d/init.sql
      - ./node1.cnf:/etc/mysql/conf.d/custom.cnf
    networks:
      - mariadbnet

  maria2:
    image: mariadb:11.7.2
    container_name: maria2
    environment:
      MYSQL_ROOT_PASSWORD: passwd
    ports:
      - "3308:3306"
    depends_on:
      - maria1
    volumes:
      - ./init/node2.sql:/docker-entrypoint-initdb.d/init.sql
      - ./node2.cnf:/etc/mysql/conf.d/custom.cnf
    networks:
      - mariadbnet

  maxscale:
    image: mariadb/maxscale:22.08
    container_name: maxscale
    ports:
      - "4006:4006"
      - "8989:8989"
    volumes:
      - ./maxscale.cnf:/etc/maxscale.cnf
    depends_on:
      - maria1
      - maria2
    networks:
      - mariadbnet

networks:
  mariadbnet:

 

maxscale 는 4006 포트를 사용 합니다.

 

maxscale.cnf

[maxscale]
admin_secure_gui=false
threads=auto
logdir=/var/log/maxscale/
log_debug=true
admin_host=0.0.0.0

[server1]
type=server
address=maria1
port=3306
protocol=MariaDBBackend

[server2]
type=server
address=maria2
port=3306
protocol=MariaDBBackend

[monitor]
type=monitor
module=mariadbmon
servers=server1,server2
user=maxscale
password=passwd
monitor_interval=2000ms
auto_failover=true
auto_rejoin=true

[RW-Split-Router]
type=service
router=readwritesplit
servers=server1,server2
user=maxscale
password=passwd
enable_root_user=1
use_sql_variables_in=master

[Splitter-Listener]
type=listener
service=RW-Split-Router
protocol=MariaDBClient
port=4006

 

 

node1.cnf (1번 서버 mariadb 설정)

[mysqld]
server-id=1
log-bin=mysql-bin
binlog_format=row
expire_logs_days=2
innodb_snapshot_isolation=0
lower_case_table_names=1

 

node2.cnf (2번 서버 mariadb 설정)

[mysqld]
server-id=2
log-bin=mysql-bin
binlog_format=row
expire_logs_days=2
innodb_snapshot_isolation=0
lower_case_table_names=1

 

서버별로 다른 server-id 를 지정해야 합니다.

innodb_snapshot_isolation=0 의 경우 동시 호출 update 에 문제가 있어 설정했고,(관계없으면 안해도됨)

lower_case_table_names=1 은 테이블명이 대소문자를 구분하도록 되어 있어 이를 피하기 위해 설정했습니다.

 

아래 초기화 sql 파일은 docker 생성 후 처음 한 번만 실행합니다.

 

./init/node1.sql (초기화 sql 파일)

-- replication user
CREATE USER 'monitor_user'@'%' IDENTIFIED BY 'passwd';
GRANT REPLICATION CLIENT on *.* to 'monitor_user'@'%';
GRANT REPLICATION SLAVE on *.* to 'monitor_user'@'%';
GRANT ALL PRIVILEGES on *.* to 'monitor_user'@'%';
GRANT super, reload on *.* to 'monitor_user'@'%';

-- monitor user
CREATE USER 'maxscale'@'%' IDENTIFIED BY 'passwd';
GRANT ALL PRIVILEGES ON *.* TO 'maxscale'@'%';
GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%';

FLUSH PRIVILEGES;

 

./init/node2.sql (초기화 sql 파일)

-- monitor user
CREATE USER 'maxscale'@'%' IDENTIFIED BY 'passwd';
GRANT ALL PRIVILEGES ON *.* TO 'maxscale'@'%';
GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%';

FLUSH PRIVILEGES;

 

2번 노드가 slave 입니다.

 

파일은 이게 전부이고, 모두 작성 후

docker-compose up -d  를 실행하면 끝.

docker ps 명령으로 잘 실행되고 있는지 확인 가능합니다.

이제 maria1,2 서버에 각각 접속해서 필요한 query 를 실행하면 됩니다.

 

먼저 maria1

docker exec -it maria1 mariadb -u root -p

패스워드는 docker-compose.yml 에 설정한 passwd 를 입력

 

 

서버 상태를 조회합니다. (show master status;)

MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000017 |   451176 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)

MariaDB [(none)]>

 

그러면 표시되는 File, Position 을 메모합니다.

 

그다음 gtid 를 조회해야합니다. 위에서 조회한 값을 활용합니다.

MariaDB [(none)]> SELECT BINLOG_GTID_POS("mysql-bin.000017", 451176);
+---------------------------------------------+
| BINLOG_GTID_POS("mysql-bin.000017", 451176) |
+---------------------------------------------+
| 0-1-1090                                    |
+---------------------------------------------+
1 row in set (0.001 sec)

MariaDB [(none)]>

 

ctrl + D 를 누르면 빠져나올 수 있습니다.

 

이제 2번 서버로 접속합니다.

[pduser@click maxscale]$ docker exec -it maria2 mariadb -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 285
Server version: 11.7.2-MariaDB-ubu2404-log mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

 

그리고 두 query 만 수행하면 됩니다. 그러고 나서 start slave 를 하게되면 설정이 마무리됩니다.

CHANGE MASTER TO MASTER_HOST='maria1',MASTER_PORT=3306,MASTER_USER='monitor_user',MASTER_PASSWORD='passwd',MASTER_LOG_FILE='mysql-bin.000017',MASTER_LOG_POS=451176,master_use_gtid=slave_pos;
set global gtid_slave_pos='0-1-1090';

start slave;

 

콘솔에서 아래 명령으로 서버 상태를 조회할 수 있습니다.

[pduser@click maxscale]$ docker exec -it maxscale maxctrl list servers
┌─────────┬─────────┬──────┬─────────────┬─────────────────┬──────────┬─────────┐
│ Server  │ Address │ Port │ Connections │ State           │ GTID     │ Monitor │
├─────────┼─────────┼──────┼─────────────┼─────────────────┼──────────┼─────────┤
│ server1 │ maria1  │ 3306 │ 10          │ Master, Running │ 0-1-1090 │ monitor │
├─────────┼─────────┼──────┼─────────────┼─────────────────┼──────────┼─────────┤
│ server2 │ maria2  │ 3306 │ 10          │ Slave, Running  │ 0-1-1090 │ monitor │
└─────────┴─────────┴──────┴─────────────┴─────────────────┴──────────┴─────────┘
[pduser@click maxscale]$

이렇게 Master, Slave 가 잘 실행되면 끝입니다.

 

DB접속은 maxscale 서버를 통해 하면 됩니다. user 생성은 개별 서버에서 각각 하면 되며,

database 생성이나 테이블 생성등은 maxscale 4006 포트를 통해 접속 후 하게되면 양쪽에 모두 적용됩니다.

엄밀히 얘기하면 Master에 적용 후 Slave 에 복제하는 형태가 됩니다.

 

HA테스트 방법

- docker stop maria1 명령으로 1번 서버를 끄면 2번 서버가 Master로 전환됩니다.

- 이후 docker start maria1 명령으로 1번 서버를 시작하면, 1번서버가 Slave 상태로 구동됩니다.

- 이를 failover 라고 합니다.

failback 기능은 없기 때문에 이렇게 서버가 구동되고 나서는 master 를 다시 1번 서버로 전환해줘야 합니다.

이 상태에서 2번 서버를 내린다고 해서 자동으로 처리가 되지 않거든요.. 꼭 전환을 해줘야 다시 failover가 동작합니다.

전환은 아래 명령으로 할 수 있습니다. 이를 switchover 라고 합니다.

 

docker exec -it maxscale maxctrl call command mariadbmon switchover monitor server1 server2

 

 

데이터 insert 도 해가면서 테스트했는데 잘 동작함을 확인했습니다!

 

추가로 서버 상태 모니터링은 MaxScale 웹 UI로 확인할 수 있습니다.

 

서버의 8989 포트로 접근하면 위와 같은 화면이 나옵니다.

초기 계정인 admin 패스워드 mariadb 로 접속하면

 

 

 이런 화면이 나오며 실시간으로 확인가능합니다. 정보 업데이트까지 몇 초 걸리니 바로 확인하고 싶으면 쉘에서 명령어로 확인하시면 됩니다.

 

반응형