TL; DR
- Galera Cluster를 통해 모든 노드가 활성화된 Multi-Master 구성 가능
- 기존 데이터가 크다면 신규 노드 Join시 동기화에 필요한 시간 증가
- xtrabackup을 통해 동기화 이전의 데이터를 미리 복제해두면, Join에 필요한 시간 줄이기 가능
1. Intro
On-prem MySQL 클러스터를 사용하면서, Master-Slave의 구조인 MySQL Replication 대신 Multi-Master 구조인 Galera cluster for MySQL을 사용하였다.
M-S 구조의 Replication에서의 Master fail시 Failover하는 경우, Slave에서 완전히 동기화 되어있음/작동 성공의 불안함이 있다. 상대적으로 Multi-Master 구조의 Galera Cluster는 참여하는 노드들이 M/S 여부 상관없이 데이터를 받고 쓸수있다. 또한 binlogs-relaylog replay의 논리적인 방식 대신 rsync, xtrabackup 등의 물리적인 방식으로 동기화가 진행되어 상대적으로 빠르게 동기화 될 수 있기에 이를 사용하였다.
그러나 일부 설정 변경 및 작업을 위해 노드 재부팅이 필요한 경우, 재부팅 이후 다른 노드와의 격차로 인해 증분 동기화가 아닌 전체 동기화가 수행될 수 있다. 이러한 경우
- 일단 동기화가 완료되어야 mysql 서버가 뜨므로 불안함
- 일부 동기화 방식(rsync)등에서는 동기화 대상서버가 block되어 작동 실패 가능성
이 있다.
이전에 DB 마이그레이션시 CDC를 활용하여 기존 데이터를 전달(스냅샷)하고, 신규 데이터 변경분만을 전달하였던 것(증분복제)처럼, Galera cluster에서 또한 기존노드의 데이터를 신규노드로 전달하고, 전달과정의 차이점만 증분복제하고자 하였다. 테스트 결과 노드간 동기화 방식을 xtrabackup을 사용하고, xtrabackup의 백업/복원으로 데이터를 전달하면 전체 xtrabackup을 통해 동기화 하는 대비 적은 시간으로 수행할 수 있었다.
2. Galera Cluster Overview
GALERA CLUSTER FOR MYSQL AND MARIADB THE TRUE MULTI-MASTER
Galera Cluster for MySQL is a true Multimaster Cluster based on synchronous replication. Galera Cluster is an easy-to-use, high-availability solution, which provides high system uptime, no data loss and scalability for future growth.
Galera Cluster for MySQL은 동기식 복제를 기반으로 한 진정한 멀티마스터 클러스터입니다. Galera Cluster는 사용하기 쉽고 고가용성을 갖춘 솔루션으로, 높은 시스템 가동 시간, 데이터 손실 및 미래 성장을 위한 확장성을 제공합니다.
https://galeracluster.com/products/
Galera cluster는 상술하였듯 동기식 복제를 기반으로한 MySQL 클러스터이다.
전체 클러스터에 대한 소개대신, 이번 주제에서 다를 데이터 동기화(State Transfer)에 관한 절차만 설명하면 다음과 같다
2.1. State Transfer
Galera cluster에서 노드간 데이터를 동기화할때 (State Transfers) 두가지 방식을 제공한다
- State Snapshot Transfer (SST): 노드의 전체 상태의 스냅샷을 전송
- Incremental State Transfer (IST): 누락된 트랜지션만 전달
State Snapshot Transfer (SST)
클러스터에 새로운 노드(Joiner)가 추가될시, 기존 노드(SYNCED) 중 하나(Donor)에서 전체 데이터 사본을 전송받는 SST 절차를 수행한다. 크게 다음과 같은 2개의 방식으로 나눌 수 있다.
- 논리적 방식
mysqldump
사용- Donor 노드는 전송간 READ-ONLY 상태
FLUSH TABLES WITH READ LOCK
- 제일 느리며 권장되지 않음
- 물리적 방식
rsync
,rsync_wan
,xtrabackup
등 활용해서 데이터 파일을 서버간 직접 전송- mysqldump보다 빠르지만 클러스터내 노드간 가능한 동일한 구성값 유지 필요
xtrabackup
같은 일부 방법은 non-Blocking 하는 Donor가 될 수 있음

Incremental State Transfer(IST)
Joiner노드의 상태를 식별하여, 전체 state 대신 누락된 transaction만 전송함
각 galera cluster는 고유한 클러스터 UUID를 갖고있으며 각 노드별로 cache파일 (GCache)를 갖고 있다. 누락된 부분이 식별되고/cache에 존재하면 IST, 그렇지 않다면 SST를 수행한다
- 수행 조건
- Joiner Node state UUID가 기존 클러스터와 동일하며 위치(seqno)가 식별가능한 경우
- uuid가 없거나, 동일하지않다면(=신규) 전달해올 데이터가 많아 SST 수행
- 누락된 데이터가 기존 노드의 Write-set Cache(GCache)에 남아있을 경우
- 아래의 Joiner의 state는
353312ba-edc2-11ef-81a3-839c4bf2e822:39930
- 기존 SYNCED의 state가
353312ba-edc2-11ef-81a3-839c4bf2e822:45621
라고 가정할 시, - sequence number 45621과 39930 간의 데이터가, 기존노드의 GCache에 남아있으면 IST / 아니라면 SST
- 아래의 Joiner의 state는
- Joiner Node state UUID가 기존 클러스터와 동일하며 위치(seqno)가 식별가능한 경우
# /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: 353312ba-edc2-11ef-81a3-839c4bf2e822
seqno: 39930
safe_to_bootstrap: 0
2.2. Write-set과 Gcache
- GCache (Write-set Cache)
- 각 노드에서 생성된 write-set(ws)을 임시로 저장
- 노드에서 트랜잭션 수행시 ws를 GCache에 저장함
- grastate.dat과 같은 경로의 galera.cache로 저장되며 기본 사이즈는 128MB
- Write-set 및 Binlog와의 차이점
- 정의
- ws: 트랜잭션에서 변경된 행들의 해시값 집합
- binlog: MySQL의 모든 변경사항을 기록한 로그파일
- 주요 목적
- ws: 복제 충돌 감지와 병렬 실행 최적화 > 성능 최적화에 집중
- binlog: 데이터 복구 및 복제를 위한 전체 변경사항 기록 > 복제 안정성에 집중
- 사용 범위 및 크기
- ws: 주로 group replication에서 사용, 작은 크기
- binlog: 백업, 복구, 마스터-슬레이브 복제등에서 사용, 큰 크기
- 정의
- write-set은 MySQL에서는 없고 Galera 에서만 사용
- 순수 mysql5.7이 아닌 mysql-5.7-wsrep(write-set replication) 사용
- mysql8.0에서 Group Replication 기능 추가, ws와 유사한 동작원리
3. 문제점) Blocking SST의 수행시간 길어짐
- binlog 설정을 위해 node02를 재시작하던 중, state 동기화가 깨져 IST대신 SST 동기화가 실행
2025-02-01T08:33:01.295619+09:00 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2025-02-01T08:33:01.295650+09:00 0 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set.
2025-02-01T08:33:01.467566+09:00 0 [ERROR] Failed to open log (file './mysql-bin.000002', errno 2)
2025-02-01T08:33:01.467572+09:00 0 [ERROR] Could not open log file
2025-02-01T08:33:01.467574+09:00 0 [ERROR] Can't init tc log
2025-02-01T08:33:01.467575+09:00 0 [ERROR] Aborting
2025-02-01T08:33:03.295839+09:00 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2025-02-01T08:33:03.295889+09:00 0 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set.
2025-02-01T08:33:04.310177+09:00 2 [Warning] WSREP: Gap in state sequence. Need state transfer.
2025-02-01T08:33:05.969823+09:00 0 [ERROR] Failed to open log (file './mysql-bin.000002', errno 2)
2025-02-01T08:33:05.969829+09:00 0 [ERROR] Could not open log file
2025-02-01T08:33:05.969830+09:00 0 [ERROR] Can't init tc log
2025-02-01T08:33:05.969832+09:00 0 [ERROR] Aborting
rsync
방식은 blocking 방식이므로 Node01의 상태가 Synced > Donor 로 변경될시 READ LOCK 가능성- The donor node is blocked with a read lock during the SST
- 전체 datafile 용량이 1TB라고 가정하고, rsync로 파일전송이 약 100MB/s 한다면 > 약 2시간 47분 예상
- wsrep_sst_donor 옵션으로 donor가 될 node 지정 가능
4. 해결책) Non-Blocking xtrabackup 사용
xtrabackup
방식은 MyISAM 테이블(시스템 테이블) 복제시에만 block을 수행하며, 그외에는 non-blocking- 그래도 1TB 정도의 용량을 옮기기에 불안함
- 기존 CDC처럼 스냅샷과 변경분을 분리하여 변경이 없는 데이터를 먼저 동기화하고 변경분만 동기화하면 빠르고 금방 끝나지 않을까
- xtrabackup을 통해 사전 데이터 전송 후 동기화 활성화
# 기존 backup 파일 제거
rm -rf /mysql-backup/*
# 기존 노드에서 galera cluster 정보를 포함한 xtrabackup 백업파일 생성
xtrabackup --backup --target-dir=/mysql-backup/base/ --galera-info
# 백업파일을 신규 노드로 전송
rsync -a /mysql-backup/ root@IP_NODE_SECONDARY:/mysql-backup
# 신규 노드에서 복원
xtrabackup --prepare --apply-log-only --target-dir=/mysql-backup/base
# 기존 mysql 정보 제거 후 스냅샷 구성
rm -rf /var/lib/mysql/*
rsync -avrP /mysql-backup/base/ /var/lib/mysql/
# xtrabackup_galera_info 참고하여 grastate.dat 작성
nano /var/lib/mysql/grastate.dat
# 권한 변경 후 mysql 노드 시작
chown -Rf mysql.mysql /var/lib/mysql
systemctl start mysql
이후 약 100G가량의 데이터로 사전 테스트 수행한 결과,
- 일반적인 join 수행시, SST를 통해 약 10여분의 시간 소요후 신규노드가 Join
- 사전 데이터 이전 이후 IST를 통한 조인 > 약 2분의 시간(IST)이후 Join
IST를 수행하기 위해서는 백업 데이터를 노드간 전송하고 준비하는 동안의 트랜잭션이 GCache에 남아있어야 하므로 GCache의 값을 사전에 조정하여야 한다.
wsrep_provider_options="gcache.size=2G"
- DB 재시작이 필요한 파라미터
5. Outro
위의 절차를 통해 사전 bootstrapping 된 신규노드를 기존 노드에 join하는 과정을 알아보았다.
그러나 xtrabackup 사용이 유저정보, DB 설정값들에 필요한 시스템 테이블을 복제시에만 block이 걸리고, 해당 시간은 그렇게 오래 걸리지 않는다. 이후 InnoDB 테이블을 전달시에는 기존 xtrabackup의 동기화방식을 통해 non-blocking 동기화가 진행되므로 필요한 절차인가 싶은 의문이 들기는 하지만.. 그래도 작동중인 클러스터는 그대로두고, 변경 or 장애가 발생할 수 있는 작업시간을 줄이는것으로 의의가 있다고 생각한다.