데이터베이스 따라잡기

복제

meellon 2026. 7. 1. 05:30

학습 목표

Primary-Replica(Leader-Follower) 토폴로지에서 쓰기·읽기가 어떻게 나뉘는지 설명할 수 있다.

동기·비동기·반동기 복제의 지연·가용성·일관성 트레이드오프를 설명할 수 있다.

Replication lagstale read·read-your-writes 실패로 이어지는 방식을 설명할 수 있다.

WAL·binlog 기반 물리·논리 복제 개념을 설명할 수 있다.

Failover·split-brain 위험과 운영에서 점검할 항목을 설명할 수 있다.

문제 상황

  • 단일 Primary에 읽기가 몰려 CPU·I/O 100%
    • SELECT10배 늘었는데 쓰기 DB 직접 조회
  • Replica에 방금 쓴 주문이 안 보인다
    • Primary COMMIT 직후 Replica SELECTlag 2초
  • 동기 복제로 RPO=0 목표 → Primary COMMIT 느려짐
    • Replica 1대 다운 시 쓰기 전체 멈춤
  • Primary 장애 → 수동 promote — 두 Primary 동시 기동 split-brain
  • wal_level=minimal인데 streaming replica 추가 실패
    • WAL 용도·설정 부족

Part 3 MVCC·WAL까지는 한 노드 안이었다. Part 4 분산과 확장여러 노드같은 데이터전파한다.

1. Primary-Replica

복제(Replication) — Primary의 변경을 Replica에 복사데이터 사본을 유지.

역할 트래픽
Primary 쓰기 + (선택) 읽기 INSERT·UPDATE·DELETE
Replica 읽기 (기본) report, search, analytics
Standby 복제만 — promote 대기 DR, failover
Client write  →  Primary  →  WAL / binlog stream  →  Replica apply
Client read   →  Replica (optional routing)
토폴로지 설명
Single-leader 쓰기 Primary 하나 — 흔함
Multi-leader 쓰기 여러 — 충돌 해결 필요 (지역별)
Leaderless quorum read/write — Cassandra 계열
  • 앞서 WAL — 복제 스트림원천 (PostgreSQL)
  • 읽기 확장 — Replica 추가로 read throughput 선형에 가깝게 (lag 주의)

2. 복제 방식

방식 내용
Physical (streaming) WAL 바이트 그대로 PostgreSQL streaming
Logical 행·DDL 이벤트 PG logical replication, Debezium
Statement SQL 재실행 MySQL statement (비결정적 위험)
Row-based binlog 행 변경 이벤트 MySQL InnoDB 기본
-- PostgreSQL streaming (개념)
-- primary: wal_level = replica (or logical)
-- replica: primary_conninfo, recovery mode
SHOW wal_level;
SELECT pg_is_in_recovery();  -- false on primary, true on replica
-- MySQL replica status (발췌)
SHOW REPLICA STATUS\G
-- Seconds_Behind_Source, Relay_Log_Pos
  • Physical전체 DB 동일 (버전·extension 맞춤)
  • Logical테이블 단위·다른 PG 버전·CDC (CDC 편)

3. 동기 vs 비동기

모드 COMMIT 시점 RPO 가용성
Async Primary WAL local flush 후 lag만큼 손실 가능 Replica down 무관
Sync Replica apply·ack 0 (해당 replica) Replica down → 쓰기 block
Semi-sync 최소 1 replica ack 제한적 0 일부 replica 필수
Async:
  Primary COMMIT  →  client OK  →  (later) replica catch up

Sync (synchronous_commit = remote_apply):
  Primary  →  WAL send  →  Replica flush  →  ack  →  Primary COMMIT  →  client OK
PostgreSQL MySQL
synchronous_commit semi-sync plugin
synchronous_standby_names rpl_semi_sync_*
quorum — NK ack after_sync / after_commit
  • CAP 관점 — 네트워크 분단 시 sync는 가용성 vs 일관성 선택
  • Cross-region replica — RTT만으로 COMMIT 지연 — async 흔함

4. Replication lag

Replication lag — Replica가 Primary 변경적용하기까지 지연.

lag 원인  
네트워크 cross-AZ·cross-region
Replica 부하 heavy read → apply 지연
대용량 트랜잭션 bulk load — WAL 한꺼번에
단일 apply thread MySQL SQL thread 병목
Vacuum·DDL replica 충돌·lock
-- PostgreSQL lag (examples)
SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();
SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) AS lag_sec;

-- MySQL
SHOW REPLICA STATUS\G
-- Seconds_Behind_Source (estimate)
앱 증상  
Read-your-writes 실패 쓰기 Primary → 읽기 Replica 즉시
Stale dashboard report 몇 분
Unique 충돌 failover 후 순서 꼬임

앱 대응

패턴  
쓰기 후 읽기 Primary 주문 생성 → detail Primary
Session stickiness user → 같은 replica + lag 허용
Lag threshold routing lag > N초 → Primary로 read
Causal / version write_version 컬럼 — client min version

예: code/read-replica-routing.example

  • 모니터링 — lag 알람 (Observability)
  • 비동기 전제 — 비즈니스몇 초 stale 허용하는지 명시

5. 읽기 확장

  단일 Primary + N Replica
Write 한 노드 한계 동일 (Primary)
Read Primary 공유 분산
일관성 강함 lag 약함
비용   replica 인스턴스
         ┌─ Replica 1  ← report
Primary ─┼─ Replica 2  ← search
         └─ Replica 3  ← analytics
주의  
Hot spot Primary 쓰기 나눔
Replica lag read 품질
Connection pool replica 마다 pool
Temp table·sequence replica 쓰기
  • Connection pool·ORM — read/write datasource 분리 (실무 편)
  • Replica too many — Primary WAL send 부하

6. Failover 개요

Failover — Primary 장애 시 Replica를 새 Primary승격.

단계  
Detect health check·heartbeat timeout
Elect 하나만 promote — quorum·orchestrator
Promote pg_promote() · CHANGE REPLICATION SOURCE
Rewire DNS·VIP·proxy → Primary
Old primary fencing — split-brain 방지
위험  
Split-brain Primary — 양방향 쓰기
Data loss async — 미복제 WAL
Sequence·GTID gap promote 후 중복 id
Brain split auto-failover flapping수동 runbook 병행
도구  
Patroni PG HA — etcd leader
Orchestrator MySQL topology
RDS / Cloud SQL 관리형 failover
Pgpool / HAProxy routingpromote별개
  • Failover ≠ load balancing쓰기 대상 하나
  • DR drill분기마다 promote 연습
  • 앞서 WAL 아카이브 — PITR + replica 조합

7. 체크리스트

항목 확인
wal_level / binlog streaming·logical 충족
Sync policy RPO vs latency 합의
Lag alert seconds threshold
App routing write 후 read Primary?
Failover 자동 vs 수동 runbook
Split-brain fencing·STONITH
Replica read-only 쓰기 실수 차단

예시 SQL·설정: code/replication-notes.sql

8. 정리

  • Primary-Replica — 쓰기 한 곳, 읽기 확장
  • Async — 빠른 COMMIT, lag·손실 tradeoff · Sync — RPO , 가용성
  • Replication lagstale read — 앱 routing·version 필요
  • WAL/binlog — physical 스트림 vs logical CDC
  • Failoversplit-brain·data lossquorum·drill

다음에 다룰 것

  • 파티셔닝과 샤딩
  • range/hash 파티션, 샤드 키, 핫스팟

해당 내용은 Database System Concepts, 7/E (Avraham Silberschatz, Henry F. Korth, S. Sudarshan), Designing Data-Intensive Applications (Martin Kleppmann) 의 내용을 기반으로 합니다.

'데이터베이스 따라잡기' 카테고리의 다른 글

분산 트랜잭션 개요  (0) 2026.07.03
파티셔닝과 샤딩  (0) 2026.07.02
MVCC  (0) 2026.06.30
로깅과 복구  (0) 2026.06.29
데드락과 타임아웃  (0) 2026.06.28