DB 이중화
1. DB 이중화의 필요성
1) 1대의 DB 서버만을 사용하는 경우
장애 시간 = db 서버 복구 시간.
2) 2대의 DB 서버를 사용하는 경우 (이중화 X)
이중화하지 않은 상태로 각각 db 서버를 아래와 같이 2대를 동작시킨다.master ip: 192.168.0.100slave ip: 192.168.0.200
이때, master가 문제가 생기면 slave를 바라보도록 관련자들이 작업을 하면 된다.
장애 시간 = 접근 db 서버 ip만 변경하는데 걸리는 시간.
3) 2대의 DB 서버를 사용하는 경우 (이중화 X)
이제 virtual ip (가상 아이피, 이하 vip)를 사용하여 db 서버 2대를 지정하여 본다.master vip: 192.168.0.300slave vip: 192.168.0.300master에 붙어있던 connection들은 서버의 reconnect 로직에 의해 동일한 vip를 가지는 slave에 connection이 붙게된다.
장애 시간 = 장애 발생 후 서버의 reconnect 완료에 걸리는 시간.
위와 같은 3가지 케이스는 장애시간을 점점 줄이는 방안으로 설계되었지만, 최종적으로 DB 복제 구성 & VIP & 자동화를 함으로써 장애 시간을 더욱 더 줄일 수 있다.
여기서의 자동화의 예시로, 장애가 발생한 경우 failover(커넥션 관리 및 VIP 변경)등을 예로들 수 있다.
2. 이중화 방안
1) HW(Hardware)의 이중화

Master(Standby)는 평상시에는 사용하지 않다가, Master(Active)를 failover 하는 용도로만 사용하게 된다.
- 단점
RHCS 솔루션 구매 필요 ex) OS Cluster.
고비용의 shared disk 필요
2) Disk 복제
DRBD + Corosync + Pacemaker로 구성

별도의 license나 고성능 disk 없이 사용이 가능하다. 평상시에 Master(Active)쪽의 데이터를 네트워크를 통해 Master(Standby)에 복제한다.
- 단점
네트워크 latency(지연 시간)에 영향을 받는다.
위 2가지 방식은 모두 Master(standby) 서버의 경우 failover 시에만 사용이 가능하다는 것과 백업을 위한 추가 서버가 필요하다는 단점이 있다.
3) MySQL Replication
기본적으로 동기(모두합의,다수합의),비동기,반동기(1곳이라도 합의) 복제 방식이 내부적으로 있다는것을 인지하자
기본 방식들
- Single Master & Single Slave

①master에서 client가 query를 실행하면
② 데이터가 변경되는 insert, upda te, delete의 경우binary log라는 파일에 기록이 되고
③ mysql에서 query가 실행된다.
④slave에서는binary log를 감시하다가, 새로운 query가 들어오게 되면 해당 정보를slave의relay log로 가져오기 위해,master에게 새로운 query를 요청한다.
⑤master는slave의 요청을 받아binary log에 적힌 쿼리를slave로 전달하면서 전달 되었다는 것을 보장받기 위해 응답을 기다린다.
⑥slave는master로부터 새로운 query를 잘 받았다는 응답(ACK)을 보내고
⑦master는slave로부터 ACK를 받으면 client에게 OK 시그널을 보낸다.
이렇게master의 변경사항이slave의relay log에 작성됨을 보장한다.
⑧ 그리고slave의 mysql에서 query를 실행함으로써master에 적용된 데이터가slave에도 적용되게 된다.
- Single Master & Multi Slave
1:1 복제구성과 마찬가지로 slave의relay log에서는master의binary log를 감시하고 query를 요청한다. 그 후master는 응답(ACK)를 기다리는데, 이때master는 하나의slave에서라도 응답(ACK)를 받게 되면 client에게 OK 시그널을 보낸다.
구체적인 이중화 방법들
MMM(Multi - Master Replication Manager)
- Perl 기반의 Auto Failover Open Source
- DB 서버에서 에이전트 실행 이 후 MMM 모니터와 통신을 하는 방식 (Health chekc, Failover 수행)
- Monitor <-> Agent 통신방식
기본 개념
- MySQL에서 여러 master/slave 노드를 두고 가상 IP(VIP) + 에이전트를 이용해 자동 failover/리커버리를 지원하는
- 실제로는 Active Master (write) + Passive Master (대기용) 구조가 많음
복제 방식
- MySQL의 비동기 복제(asynchronous replication) 기반
- 일반적으로 Master ↔ Master 간 이중 복제 설정 (circular replication)
- 추가적으로 Master → Slave 복제도 함께 운영 가능
장애 처리
- Active Master 장애 → Passive Master를 VIP로 승격 (자동/수동)
- 슬레이브들은 새 Master를 바라보도록 자동 재설정
- 네트워크 split-brain(두 master가 동시에 write) 위험 존재
장점
- 간단한 HA 구성 가능 (VIP 전환)
- Active-Passive 구조에서 빠른 장애 전환 가능
- Slave를 붙여 read scale-out 가능
단점
- 개발/유지보수 중단(프로젝트 사실상 deprecated)
- Split-brain 가능성 → 데이터 충돌 위험
- Circular replication 구조의 복잡성 → 데이터 정합성 깨질 수 있음
- 요즘은 MHA나 Group Replication, ProxySQL 기반 HA로 대체되는 추세
MMM의 구조
Master (Activce) 와 Master (Standby) 양방향 복제

Master (Standby) 는 데이터가 변경되지 않도록 MMM 모니터로부터 읽기모드로 제어된다.
MMM의 구조 - Slave 추가

Slave가 추가된다면 단방향 복제의 Slave가 하나씩 추가되는 구조, 이역시 Master(Active) 를 제외하고는 모두 읽기모드로 제어된다.
MMM FAILOVER 과정

Master(Active)에서 Master의 역할을 뺏는 작업을 진행한다.
- 읽기모드로 변경
- 세션 킬
- VIP 회수

Master(Standby) 혹은 Slave로 복제를 제구성한다.
복제를 재구성하기 이전에 복제지연이 있는지 확인한다.
이때 Master(Standby) 기준으로 복제를 진행한다.
Master(Standby) 에 대한 읽기 모드를 해제하고
VIP를 할당한다.
FAILOVER 완료!
MMM FAILOVER의 후속처리

Master(Active)에 장애가 나고 정상적으로 복구가 완료된다면 Master(Standby)로 변경하여 역할만 변경된다.
MMM FAILOVER 과정에서 복제가 깨지는 경우
상황을 예시로 들자면
INSERT INTO TABLE VALUES (101, 'B');
위의 쿼리를 Master(Active) 에서 진행한다고 가정해보자.
이때 Slave가 101 에 대한 복제를 진행하고 완료 후 Master(Active) 에게 ACK 을 보낸다.
(아직 Master(Standby)는 복제를 하지 못한 상태)
이 당시에 Master (Active)에서 장애가 발생하였다. 그러면 위에서 언급하였듯이 Master (Standby)가Active로 승격되고 101에 대한작업을 다시 진행하게된다.
여기서 문제가 발생한다. Slave는 이미 복제를 통해서 101을 가지고 있으나 Standby에 대한 권한이 올라갔으므로 또 한번의 복제과정이 일어난다. 이때 PK오류가 발생하는 경우가 있다.(쓰기 충돌 문제)-> 데이터 유실
Multi Slave 환경에서 미약하지만 복제 Crash 가능성이 존재한다.
대안으로 MHA가 등장, MHA는 처음부터 Single Master 구조를 전제로 설계되어 안전하게 운영 가능
MHA (Master High Availability)
- Perl 기반의 Auto Failover Opensouce
- Agentless 방식
기본 개념
- MySQL replication 환경에서 master 장애 감지 후 자동 failover를 수행하는 툴
- Slave 중 하나를 새로운 master로 승격, 나머지 슬레이브는 새 master를 따르도록 재구성
복제 방식
- 기본적으로 Master-Slave 비동기 복제 기반
- Semi-sync replication과도 함께 사용할 수 있음
- binlog event를 최대한 수집/적용하여 데이터 손실 최소화
장애 처리
- MySQL에서는 Lossless Replication은 지원한다. 이는 Master에서 데이터 변화가 진행되면 Slave 어딘가에 반드시 변경이력이 남아있다는 것을 보장한다.
- MHA에서는 장애 발생 시 가장 최근에 변경된 Slave를 Master DB로 승격 시킨 후 Lossless Replication을 통한 relay log로 데이터 복구를 수행한다.
- 장애 발생부터 Master DB 승격, 데이터 복구까지 걸리는 시간은 10~30초 이다.
- 기존 Master 장애 발생 시:
- 슬레이브 중 최신 데이터를 가진 노드 탐색
- 해당 노드를 새 master로 승격
- 다른 슬레이브들은 새 master에 재연결
- Failover 시간 동안 Write 중단 발생 (10~30초)
- Read는 Slave에서 지속 가능
장점
- 오픈소스 기반, 성숙된 프로젝트
- MySQL 환경에서 널리 사용됨 (특히 클라우드 전 이전 시대에 인기 많음)
- 자동 failover로 가용성 향상
- 기존 MySQL replication 환경과 호환성 높음
단점
- Failover 시 짧은 Write 불가 시간 발생
- 구성 복잡 (MHA Manager, Node 에이전트 필요)
- Master 장애 복구 후 재참여 어려움 (보통 dump & sync 필요)
- MySQL 엔진 내장 기능이 아니므로 추가 툴 관리 필요
MHA 구조
- MHA Manager, Master, Slave 서버로 총 3개로 구성되어 있으며, 상황에 따라서는 1개의 Master와 N개의 Slave로 최소 2대까지 사용할 수 있다.
- Master와 Slave는 하나의 VIP를 공유하며 DB 접속은 해당 VIP를 이용하며 장애 발생 시 VIP를 이용하여 절제를 진행한다.
- 또한, Failover의 후속처리로 다시 살아난 Master A에 대해 현재 운영중인 Master B, Slave C와의 관계를 자동으로 만들어주지 않기 때문에, 복제를 재구성해주는 작업을 별도로 해주어야 한다.

MHA의 장애 체크
- MHA Manager가 3초마다 마스터 DB를 CONNECT / SELECT / INSERT 체크하며 3회 실패 시 장애로 인식하여 FailOver를 수행한다.
MHA 구조

하나의 마스터와 Slave 구조로 이루어져 있다.
모두 단방향 복제로 이루어져있다.
MHA FAILOVER 후속처리

마스터 DB가 장애가 나는 경우 더이상 마스터 DB는 정상적인 데이터를 갖을 수 없다고 판단하여 마스터와 기존 Slave와의 복제를 끊는다.
나머지 DB들로 복제를 재구성한다.
마스터 DB가 정상작동을 한 이후에도 작업을 완전히 끊었기 때문에 복제를 재구성해주는 작업이 필요하다.
FAILOVER대상
MHA의 FAILOVER대상은 MMM과 다르게 기본적으로 고정되어있지 않다.
- 기준 : 가장 최신의 데이터를 가지고 있는 DB를 마스터로 승격시킨다.
위에 언급하였던 MMM의 복제 Crush 현상을 방지하기 위해서 별도의 절차를 거친다.
- 복제를 구성하는 대상 : 바이너리 로그, 릴레이 로그 파일
해당 파일을 가져와서 차이나는 데이터를 추출 한다.
만약에 Slave1 에 101이라는 데이터가 유실되었다면 바이너리 릴레이 로그 파일과 비교하여 101을 추출하여 Slave1 에 101을 저장하게 된다.
MMM과 다르게 복제 crush 현상을 방지하기 위해서 바이너리 로그, 릴레이 로그 파일을 비교하여 차이나는 데이터를 추출합니다. 따라서 가장 최신의 데이터로 업데이트가 안된 DB를 업데이트 합니다.
그런데 MHA도 기존 master가 장애 발생시 faliover 과정을 거칠텐데, Read는 계속적으로 서비스가 이어지나, Write는 승격하는 시간동안 일시적인 서비스 장애가 발생합니다 ---> Write 중단 시간까지 줄이고 싶다면 Group Replcation이 대안이 될 수 있음
mysql group replication
기본 개념
- 여러 MySQL 서버가 하나의 Group(클러스터) 를 형성
- 모든 노드가 복제 + 합의 프로토콜을 통해 데이터를 동일하게 유지
- Single-primary 모드: 하나의 노드만 쓰기 가능 (나머지는 읽기 전용)
- Multi-primary 모드: 모든 노드가 쓰기 가능 (충돌 감지/해결 필요)
복제방식
- 전통적 비동기 복제: master에서 binlog를 슬레이브로 전송 → Slave 적용 시점 불일치 → replication lag 발생 가능
- mysql group replication은 전통적 방식이 아닌 Group Communication System(GCS)를 사용
- Group Communication System:
- binlog 이벤트를 group communication system (GCS) 를 통해 모든 노드에 동시에 전파
- certification(각 노드가 충돌 여부 검사)단계
- 과반수 이상이 승인 → 모든 노드가 동시에 commit
- 결과적으로 동기적(synchronous) 복제에 가까움
장애처리
- 특정 노드 장애 → Group이 감지 후 해당 노드 제외하고 합의 계속 진행
- Primary 노드 장애 (Single-primary 모드) → 나머지 노드 중 하나를 자동으로 primary로 선출
- Multi-primary 모드라면 → 남은 노드들이 계속해서 write 가능
장점
- 내장 기능 (MySQL 5.7+ 기본 제공)
- 자동 failover, 높은 데이터 일관성
- Multi-master 지원
단점
- 합의 과정 때문에 지연(latency) 증가 → 성능은 Async replication보다 떨어짐
- 네트워크가 불안정하면 클러스터가 쉽게 쪼개짐(partition), 성능 급격히 저하(노드 간 메시지 손실, 지연 발생)
- EX) 정상: A ↔ B ↔ C 전부 서로 통신 가능
- 문제: 네트워크 불안정으로 A만 고립됨 → (A) / (B, C) 두 그룹으로 분리
- (B, C) → 2개 중 2개 = 과반수 확보 → 그룹 계속 운영
- (A) → 혼자라 과반수 불가 → 자동으로 read-only 모드 전환 (격리)
- 고립된 노드는 자동으로 격리되므로, 서비스 입장에서는 정상 노드 수가 줄어드는 효과 발생(단점)
- 충돌(Conflict) 발생 시 트랜잭션이 자동 롤백 → 애플리케이션 로직에서 재처리 필요
- 운영 복잡도 높음 → ProxySQL, MySQL Router 등과 함께 사용해야 안정적

MySQL의 Migration은 다음과 같은 순서로 동작함
- 클라이언트(Application)에서 Commit 을 수행
- Connection Thead 는 스토리지 엔진에게 해당 트랜잭션에 대한 Prepare(Commit 준비)를 수행
- Commit 을 수행하기 전에 먼저 Binary Log 에 변경사항을 기록
- 스토리지 엔진에게 트랜잭션 Commit 을 수행
- Master Thread 는 시간에 구애받지 않고(비동기적으로) Binary Log 를 읽어서 Slave 로 전송
- Slave 의 I/O Thread 는 Master 로부터 수신한 변경 데이터를 Relay Log 에 기록(기록하는 방식은 Master 의 Binary Log 와 동일)
- Slave 의 SQL Thread 는 Relay Log 에 기록된 변경 데이터를 읽어서 스토리지 엔진에 적용
*Binary Log : , Create, Drop과 같은 DDL문과 Insert, Update, Delete와 같은 DML문을 통해서 데이터의 변화가 발생할 경우 해당 이벤트들을 기록하는 로그 파일
*Relay Log : I/O thread를 통해서 받은 이벤트를 로컬에 저장되는 파일 있는 file에 저장. 보통 SQL thread가 이벤트를 읽고 나면 지우지만, SQL thread가 멈추어 있으면 relay log는 계속해서 크기가 커짐
이중화시 mysql 내부 복제 방식

✅ 전통적인 MySQL 복제
Async Replication
- Master: 트랜잭션 실행 → binlog 기록 → commit 완료 → 클라이언트 응답
- Slave: 이후 binlog 이벤트를 받아 relay log에 저장 → SQL 스레드가 적용
👉 Master는 Slave ACK를 기다리지 않음 → 빠르지만 장애 시 데이터 유실 가능
Semi-sync Replication
- Master: 트랜잭션 실행 → binlog 기록
- Slave가 binlog를 받았다고 ACK 하면 → Master commit → 클라이언트 응답
- Slave SQL 스레드는 이후 apply
👉 최소 1 Slave에는 이벤트 도착 보장, 하지만 Slave 적용 시점은 여전히 비동기
✅ MySQL Group Replication (GCS)
여기서 구조가 확 달라집니다.
1.클라이언트 트랜잭션 실행 (서버1에서)
- 로컬에서 트랜잭션 실행하지만 commit 직전에 멈춤 (pre-commit 상태)
2.트랜잭션 이벤트를 그룹으로 전파 (enqueue to group)
- binlog 이벤트를 Group Communication System(GCS)을 통해 다른 노드들로 전달
3.Certification 단계 (각 노드)
- 각 노드가 트랜잭션의 충돌 여부 검사
- 예: 같은 row에 동시에 update 충돌 → reject
4.Majority ACK
- 과반수 노드가 "OK" → 트랜잭션 commit 확정
- reject 시 해당 트랜잭션은 rollback
5.Commit 동기화
- 모든 노드가 같은 순서로 트랜잭션 commit → 데이터 정합성 확보
🔹 실무 선택 기준
- 과거: MMM도 썼지만, 안정성 문제 때문에 MHA로 많이 전환.
- 현재 트렌드:
- MHA → 여전히 전통적인 환경에서 사용됨.
- 클라우드 환경에서는 Proxy 기반 (HAProxy, ProxySQL, MaxScale) 과 MySQL Group Replication, InnoDB Cluster, Galera Cluster 같은 솔루션이 대세.
- 예: AWS Aurora/MySQL → 자체적으로 Failover 내장.
✅ 정리
- On-premise, 전통적 운영 → 아직도 MHA + Semi-sync 조합 많이 씀
- 최신 구축, 강한 정합성 요구 → Group Replication(InnoDB Cluster) 로 점점 이동
- 클라우드 환경 → 고민할 필요 없이 Aurora, CloudSQL 같은 매니지드 DB 선택
- MMM은 현재 실무에서는 거의 쓰지 않음.
✅ 각 방식의 특성 요약
| 방식 | 일관성 | 가용성 | 성능 | 특징 |
|---|---|---|---|---|
| Async Replication | 약함 (유실 가능) | 높음 | 빠름 | 단순, 리스크 큼 |
| Semi-sync Replication | 중간 (유실 ↓) | 높음 | 약간 느림 | MHA와 조합 多 |
| MHA (with Async/Semi-sync) | 중간 | 중간~높음 | 빠름 | 전통적, 수 초 단위 failover |
| Group Replication / InnoDB Cluster | 강함 (majority commit) | 높음 | 느림 (latency ↑) | 공식 차세대 솔루션 |
| Galera Cluster (Percona, MariaDB) | 강함 (모든 노드 동기 commit) | 높음 | 더 느림 | 글로벌 서비스에 부적합 |
| Cloud Managed DB (Aurora, CloudSQL 등) | 강함 | 매우 높음 | 최적화됨 | 운영 편의성 최고 |
출처:
https://saramin.github.io/2021-09-28-mysql-group-replication/
https://halkrine.tistory.com/83
'나의 주니어 개발 일기 > DB' 카테고리의 다른 글
| 샤딩?파티셔닝? (1) | 2025.08.29 |
|---|---|
| 커버링 인덱스, 클러스터드 인덱스, 넌클러스터드 인덱스 (1) | 2024.07.26 |
| DB Replication 해보기 (master-slave) by 도커 컴포즈 (2) | 2024.05.17 |
| 클러스터드 인덱스 vs 넌클러스터드 인덱스 (0) | 2024.05.08 |
| 커버링 인덱스 사용했을때 성능차이 (1) | 2024.04.23 |