카테고리 없음

🚨 PostgreSQL 4노드 HA 구성부터 WAL 장애 해결까지 (repmgr 실전 정리)

우루쾅 2026. 5. 3. 20:33
728x90
반응형
SMALL

 

제가 서비스를 운영하면서 직접 겪은 . . .

primary 1대 + standby 3대 구성부터 upstream 변경, 그리고 장애 시 promote까지

단순 이론 말고 실제 삽질하면서 경험한 내용을 정리해서 작성해보았습니다!

 

 

1️⃣ 4노드 HA 구성

목표 구조

기존 프로젝트에서는 primary 와 standby 로 구성된 ha 상태의 DB 서비스를 운영하고 있었습니다.

이해를 돕기 위해 각각의 DB 01, 02, 03, 04 같이 순번을 붙혀 설명하겠습니다.

db01 (primary)
 └─ db02 (standby)

 

그러던 중 DB 서버의 OS 업그래이드를 하게 되었습니다.

In-place 업그레이드를 진행하면 라이브러리나 DB extension 이 깨질 수 있기 때문에

DB를 먼저 Standby 로 복제를 떠서 운영하다가 진행하는 것으로 구성하였습니다.

db01 (primary)
 ├─ db02 (standby - 기존)
 ├─ db03 (standby - 신규 OS)
 └─ db04 (standby - 신규 OS)

 


기본 구성 흐름

1. standby clone (db03, db04)

먼저 db03 과 db04 를 standby 로 등록을 하기 위해 db01(primary) 데이터를 clone 떠서 데이터를 동기화 시킵니다.

repmgr standby clone -h db01 -U repmgr -d experdb -F

 

 

2. standby 기동 후 standby 등록

# DB 기동
pg_ctl start

# Standby 등록
repmgr standby register -F

 

3. 결과 확인

[experdb@db04 etc]$ repmgr service status
WARNING: following problems with command line parameters detected:
  database connection parameters not required when executing SERVICE STATUS
 ID | Name | Role    | Status    | Upstream | repmgrd     | PID    | Paused? | Upstream last seen
----+------+---------+-----------+----------+-------------+--------+---------+--------------------
 1  | db01 | primary | * running |          | running     | 235708 | no      | n/a
 2  | db02 | standby |   running | db01     | running     | 126832 | no      | 0 second(s) ago
 3  | db03 | standby |   running | db01     | not running | n/a    | n/a     | n/a
 4  | db04 | standby |   running | db01     | not running | 28389  | no      | 8 second(s) ago

 

📌 내부 동작 이해 (핵심)

Replication은 데이터 복사가 아니라 WAL replay입니다.

# INSERT → WAL 기록 → standby 전달 → standby에서 replay
db01 → WAL → db02
     → WAL → db03
     → WAL → db04

 

2️⃣ 클러스터 분리 (DB01/02 vs DB03/04)

OS 작업 준비가 되면 기존 서비스와 분리해야 합니다.

 

📌 목표 구조

서버 db01 과 db02, 서버 db03 과 db04 를 분리하여 운영하고 

기존  db01, 02 에 붙어있던 서비스를 db03, 04 로 전반적인 교체 작업을 진행해야 합니다.

 

여기에서 클러스터 분리에 대하여 집중 공략하겠습니다!

클러스터 A
db01 → db02

클러스터 B
db03 → db04

 

 

1. 기존 primary(db01) 중지

primary 가 2개 생성되면 split-brain 이 발생하기 때문에 
기존 사용하는 primary 를 다운 시킵니다.

pg_ctl stop

 

2. db03을 primary로 승격

기존 standby 였던 db03 을 promote 를 통해 primary 로 승격시킵니다.

pg_ctl promote

 

3. db04를 db03에 붙이기

- db04번의 upstream-node-id 변경(기존 primary가 db01로 잡혀있기 때문에 변경 시 -F 옵션을 줘서 강제로 변경)

repmgr standby register -F --upstream-node-id=3

 

- postgresql.conf 파일에 옵션 추가(혹은 postgresql.auto.conf)

primary_conninfo = 'host=db03 port=5432 user=repmgr application_name=db04 connect_timeout=2'
primary_slot_name = 'repmgr_slot_4'

 

- postgresql.conf 파일에 shared_preload_libraries 옵션 추가 

shared_preload_libraries = 'repmgr'

 

4. repmgr 메타데이터 정리

db03 기준

DELETE FROM repmgr.nodes WHERE node_id IN (1,2);

 

db01 기준

DELETE FROM repmgr.nodes WHERE node_id IN (3,4);

📌 결과

repmgr nodes 에서 각각의 클러스터를 삭제함으로써 이중화 구성을 완전히 분리시킵니다.

db01 → db02
db03 → db04

 

3️⃣ 장애 발생 (WAL 폭증 → Disk 90%)

이중화 구성을 분리하여 운영을 한지 이틀이 지난 시점에 Disk 가 90프로 이상 차는 이슈가 발생하였습니다.(총 2TB 중 1.8TB)

디스크 사용량을 확인해보니 WAL 디렉토리가 비정상적으로 커져서 Disk 이슈가 발생한 것이였습니다.

 

정상적인 구조라면 WAL 은 아카이브 푸시를 진행한 뒤 checkpoint 이후 재사용 혹은 삭제가 되며 자동으로 정리가 되어야하지만 해당 캐이스는 특정한 이슈에 의하여 wal이 정리되지 않고 쌓이고 있었습니다.

 

📌 원인 추적

① DB 로그 확인

 

먼저 아카이브 푸시가 정상적으로 동작하는지 확인하기 위하여 db 로그를 확인하였습니다.

 

wal 은 백업을 받기 위하여 아카이브에 데이터를 복제하게 되는데 이 때 아카이브 푸시가 정상적으로 발생하지 않으면 아직 데이터를 필요로 하는것으로 판단하여 wal 을 정리를 하지 않기 때문입니다.

 

하지만 로그를 확인해본 결과 아카이브 푸시는 정상적으로 success 가 떨어지고 있었습니다.

 

② slot 확인(원인 발견!)

 

db03 에서 wal 이 계속 차고있었기 때문에 standby 에 데이터를 전달하는 과정에서

정상적으로 동작하는지 검토하기 위하여 slot 을 확인해보았습니다.

SELECT slot_name, active, restart_lsn
FROM pg_replication_slots;

 

확인해보았을 때 db03 에서 db02 의 slot 정보를 가지고 있었고,

db02 가 wal 을 아직 필요로 한다고 postgresql db 엔진에서 판단하여 wal 을 삭제하지 않고 있던 것이였습니다.

1. replication slot 존재
      ↓
2. slot의 restart_lsn 확인
      ↓
3. "이 LSN 이후 WAL은 반드시 필요"로 판단
      ↓
4. checkpoint 발생
      ↓
5. WAL 정리 시도
      ↓
6. restart_lsn보다 이전 WAL만 삭제 가능
      ↓
7. restart_lsn이 뒤로 안 움직이면 WAL 삭제 불가
      ↓
8. WAL 계속 누적

 

 

4️⃣ 해결 (Slot 삭제 + Checkpoint)

inactive slot 때문에 wal 이 정리되지 않는 것을 확인하였고 해당 slot 을 삭제하고 wal 을 정리하기로 판단하였습니다.

 

1. slot 삭제

SELECT pg_drop_replication_slot('repmgr_slot_2');

 

2. checkpoint 실행

CHECKPOINT;

 

📌 결과

이로서 wal이 정상 크기로 감소하는 것을 확인하였고 서비스 정상화 확인 완료하였습니다!

du -sh pg_wal

 

 

📌 정리!

“WAL은 쌓이는 게 아니라, 삭제 조건이 막혀서 남는다.”
대부분의 WAL 폭증 문제는 replication slot 하나에서 시작된다.

(작업은 1~2주간 정상동작 확인되었을 때 마무리된다!)

 

 

출처

https://www.enterprisedb.com/blog/repmgr-32-here-barman-support-and-brand-new-high-availability-features

 

 

 

728x90
반응형
LIST