Database

[MariaDB] Replication 적용기 - 1 (DB Setting)

KAispread 2024. 1. 5. 00:59
728x90
반응형

본 포스팅을 시작으로 Replication을 적용하는 여정에 대해 남겨보려고 한다. Replication 을 처음 접해보았거나 개념이 잘 기억나지 않는다면 이전 포스팅을 참고하자.

2024.01.03 - [Database] - [MySQL] 가용성과 확장성을 위한 Database Replication

 

[MySQL] 가용성과 확장성을 위한 Database Replication

DB Replication이 왜 필요할까? 다음과 같이 데이터베이스를 한 대만 운영하는 아키텍처가 있다고 가정해보자. 모든 데이터에 대한 읽기와 쓰기 작업은 하나의 MySQL 데이터베이스에서 수행된다. 만

rachel0115.tistory.com

 

 

다음과 같이 Master 서버에서의 데이터 변경 사항이 자동으로 Replica 서버에 반영되어 동기화시키는 것이 목표다. 실습에는 MariaDB를 사용할 예정이고 MySQL 설정 방법과 동일하다. (일부 파일 경로 제외)

본 포스팅에서 Master 서버에 위치한 데이터베이스를 MasterDB, Replica 서버에 위치한 데이터베이스를 ReplicaDB라고 칭하겠다.

 


 

실습 환경

  • Ubuntu 22.04
  • MariaDB 10.6.12

2대의 서버 인스턴스를 준비하자.

 

공통 작업

두 서버 인스턴스에 MariaDB server 패키지를 설치하자.

# MariaDB 설치
sudo apt-get update
sudo apt-get install mariadb-server

# MariaDB 서비스 상태 확인
sudo service mariadb status

# 루트 계정으로 접속
sudo mariadb -u root -p

 

Master 서버와 Replica 서버에서 사용할 USER 계정을 각각 서버 인스턴스에서 생성해준다.

CREATE USER 'kai'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'kai'@'%';
FLUSH PRIVILEGES;

 

생성한 USER 계정으로 다시 로그인한다.

$ sudo mariadb -u kai -p
Enter password: password

 

 

 

Master Server 작업

Replication 을 위한 데이터베이스를 생성하자. 필자는 기존에 있는 wemeet 이라는 이름의 데이터베이스를 사용하겠다. 테스트용도의 간단한 테이블도 하나 만들어두자.

CREATE DATABASE wemeet;

 

Replication을 위해선 Master 서버의 계정이 필요하다. 각 Replica 서버에서는 해당 계정을 통해 Master 서버와 연동하고 Binary Log를 가져오게 된다. kai_master 이름으로 Replication을 위한 계정을 생성했다.

CREATE USER 'kai_master'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'kai_master'@'%';

 

/etc/mysql/my.cnf 파일에 다음의 내용을 추가하자.

# 설정파일 수정
sudo vim /etc/mysql/my.cnf

# 다음의 내용 추가
[mariadb]
server-id = 1
log-bin = mysql-bin
binlog_format = MIXED
max_binlog_size = 500M
sync_binlog = 1
expire-logs-days = 7
binlog_do_db = wemeet
  • server-id : 서버의 ID. 레플리케이션 토폴로지 내의 서버는 각각 고유한 서버 ID를 가져야한다. 즉, 이 값은 레플리카 서버와 반드시 달라야한다.
  • log-bin : 바이너리 로그 파일 경로 (/var/lib/mysql/mysql-bin.XXXXXX 형식으로 저장됨)
  • binlog_format : 바이너리 로그의 저장 형식을 지정한다. STATEMENT , ROW , MIXED 이 3가지 중 하나를 선택할 수 있다.
  • max_binlog_size : 바이너리 로그의 최대 크기
  • sync_binlog : N개의 트랜잭션 마다 바이너리 로그를 디스크에 동기화 시킬지 결정한다. 1 은 가장 안정적이지만, 가장 느린 설정이다.
  • expire-logs-days : 바이너리 로그가 만료되는 기간 설정
  • binlog_do_db : 레플리케이션을 적용할 데이터베이스 이름 설정. 설정하지 않으면, 모든 데이터베이스 대상으로 레플리케이션이 진행된다.

 

mariadb server를 재시작해준다.

sudo service mariadb restart

 

설정을 마치고 나서 다음 2가지를 확인하면 된다.

  • 고유 서버 ID 설정
  • Binary Log 활성화

Master 서버에서 다음의 명령으로 활성화 여부를 확인할 수 있다. log_bin 컬럼 값이 'ON' 이여야한다. 

SHOW VARIABLES LIKE '%log_bin%';

 

다음의 명령으로 server-id 도 확인할 수 있다. Replication 토폴로지 내에서 server-id는 각각 고유해야한다.

SHOW VARIABLES LIKE 'server_id';

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
1 row in set (0.001 sec)

 

 

Master 서버 Binary Log 좌표값 얻기

Replication을 위해선 replica 서버가 Master 서버의 바이너리 로그 좌표를 알아야한다. 그래야 Replica 서버가 Binary Log를 현재 좌표를 기준으로 읽어서 업데이트를 수행할 수 있기 때문이다.

다음의 명령을 실행하여 좌표값을 얻어낼 수 있다. 

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000007 |      342 | wemeet       |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)

다음의 경우엔 mysql-bin.000007 파일의 342 위치 값을 갖는다는 것을 알 수 있다. 이 값을 기억해두자.

 

이미 Master 서버를 구동하고 있었을 경우엔 모든 변경 내역을 flush 하고 읽기 잠금을 걸어야한다. 데이터 변경이 발생할 경우 Binary Log의 좌표값이 계속 바뀌기 때문이다.

FLUSH TABLES WITH READ LOCK;

 

 

Replica Server 작업

Replica 서버에 고유한 server-id 값을 부여하자. 반드시 Replication 토폴로지 내에 고유한 값이여야한다.

/etc/mysql/my.cnf 파일에 다음의 내용을 추가한다.

[mariadb]
server-id = 2

 

마찬가지로 재부팅 후 server-id를 확인한다.

sudo service mariadb restart

show variables like 'server_id';

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
1 row in set (0.001 sec)

 

다음의 쿼리를 순차적으로 실행하여 Replication 설정을 입력해주자.

RESET REPLICA;

CHANGE MASTER TO
MASTER_HOST= #Master Server IP,
MASTER_USER= #Replication용 USER,
MASTER_PASSWORD= #Replication용 USER PW,
MASTER_LOG_FILE= #Master 서버 bin_log 파일,
MASTER_LOG_POS= #Master 서버 bin_log Position;
# 예시
RESET REPLICA;

CHANGE MASTER TO
MASTER_HOST= '43.202.48.141',
MASTER_USER='kai_master',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000007',
MASTER_LOG_POS=342;

 

 

GTID 사용

MariaDB 10.0 부터 Global Transaction ID가 도입되었다. GTID 를 사용하면 faliover, 안전성 등 여러 부분에서 이점이 있으므로 공식문서에서는 GTID를 사용하는 것을 권장하고 있다. 자세한 내용은 다음 공식 문서를 참조하자.

https://mariadb.com/kb/en/gtid/

다음의 쿼리문을 통해 GTID를 활성화할 수 있다.

CHANGE MASTER TO MASTER_USE_GTID = slave_pos

 

MariaDB에서 GTID를 사용할 때, current_pos와 slave_pos는 각각 Master와 Replica 서버에서의 GTID 위치를 나타낸다. 

  • current_pos
    • Master 서버에서 현재 GTID 위치를 나타낸다.
    • Master 서버에서 쓰기 작업이 진행될 때마다 current_pos가 증가한다.
    • Master 서버의 GTID 위치를 기반으로 Replication이 진행된다.
    • 쓰기 작업이 마스터에서 발생할 떄마다 GTID가 증가하므로, Master와 Replica 간의 GTID 위치를 파악하기 쉽다.
  • slave_pos
    • Replica 서버에서 현재 GTID 위치를 나타낸다.
    • Master 서버는 Master 서버로부터 복제된 GTID 위치를 기록하고 있다.
    • slave_pos는 Replica 서버에서의 마지막으로 복제된 GTID 위치를 나타낸다.
    • Replica 서버가 정상적으로 Replication 되고 있는지 모니터링할 때 사용될 수 있다.

 

Start Replication

START REPLICA 명령으로 Replication 을 시작할 수 있다.

# Replication 시작
START REPLICA;

# Replication 중지
STOP REPLICA;

# Replication 설정 리셋
RESET REPLICA;

 

다음의 명령을 통해 Replication 설정을 확인할 수 있다. Slave_IO_Running, Slave_SQL_Running 값이 Yes 라면 성공이다.

# Replica 상태보기
SHOW REPLICA STATUS\G;

*************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 43.202.68.172
                   Master_User: kai_master
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mysql-bin.000006
           Read_Master_Log_Pos: 502
                Relay_Log_File: mysqld-relay-bin.000006
                 Relay_Log_Pos: 801
         Relay_Master_Log_File: mysql-bin.000006
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
...

 

추가적으로 GTID가 활성화되었는지에 대한 여부도 확인할 수 있다.

 

테스트 용도로 Master 서버에서 INSERT 쿼리문을 수행하면?

다음과 같이 자동으로 Replica 서버에 데이터가 동기화되는 모습을 확인할 수 있다.

 

마무리

본 포스팅에서 데이터베이스 Replication 설정을 다뤘다. 다음 포스팅에서는 Spring에서 읽기 트랜잭션일때 Replica 서버에 트래픽이 라우팅되도록 설정해보겠다.

 

Reference.

https://parkadd.tistory.com/127

https://hudi.blog/database-replication-with-springboot-and-mysql/

728x90
반응형