지연 복제본은 왜 백업이 아니라 되감기 버퍼일까
누군가 운영 DB에서 잘못된 DELETE를 실행했을 때, 우리는 몇 시간짜리 복구가 아니라 몇 분짜리 판단으로 데이터를 되돌릴 수 있을까?
지연 복제본은 왜 백업이 아니라 되감기 버퍼일까
- 카테고리: infra_dev
- 예상 읽기 시간: 10분
- 오늘의 질문: 누군가 운영 DB에서 잘못된
DELETE를 실행했을 때, 우리는 몇 시간짜리 복구가 아니라 몇 분짜리 판단으로 데이터를 되돌릴 수 있을까? - 핵심 출처:
- Using delayed read replicas for Amazon RDS for PostgreSQL disaster recovery - 게시일 미표기, 2026-07-10 확인
- Configuring delayed replication with RDS for PostgreSQL - 게시일 미표기, 2026-07-10 확인
- Amazon RDS for PostgreSQL now supports delayed read replicas - 2025-08-22 게시, 2026-07-10 확인
- PostgreSQL 17 Documentation: Replication / recovery_min_apply_delay - 문서, 2026-07-10 확인
- Amazon RDS for PostgreSQL Release Notes - 문서, 2026-07-10 확인
1. 왜 지금 봐야 하나
운영 데이터베이스 장애는 항상 디스크 고장이나 리전 장애로 시작하지 않는다. 더 흔한 사고는 훨씬 평범하다.
- 배치 스크립트의
WHERE조건이 빠졌다. - 마이그레이션이 예상보다 넓은 행을 갱신했다.
- 새 배포가 잘못된 상태 전이를 대량으로 만들었다.
- 관리자 콘솔에서 실수로 테이블이나 파티션을 지웠다.
이런 사고의 무서운 점은 인프라가 “정상 동작”한다는 데 있다. DB는 요청받은 쓰기를 성실히 커밋하고, 복제 시스템은 그 잘못된 커밋을 빠르게 replica에 전파한다. 백업과 PITR(point-in-time recovery)이 있더라도 큰 DB에서는 새 인스턴스를 만들고 snapshot과 WAL을 재생하는 시간이 길어질 수 있다.
AWS는 2025년 8월 Amazon RDS for PostgreSQL delayed read replica 지원을 발표했고, AWS Database Blog는 이를 재해 복구 패턴으로 설명했다. 핵심은 단순하다. read replica가 primary를 즉시 따라가지 않고 의도적으로 몇 분 또는 몇 시간 뒤에 따라가게 만든다. 그러면 나쁜 트랜잭션이 replica에 적용되기 전, 사람이 사고를 감지하고 WAL replay를 멈춘 뒤 안전한 지점으로 복구할 수 있다.
오늘 가져갈 개념은 이것이다.
delayed replica는 백업의 대체품이 아니라, “잘못된 쓰기가 복제되기 전 잡아두는 시간 버퍼”다.
2. 핵심 개념
PostgreSQL의 물리 복제는 WAL(write-ahead log)을 standby에 전달하고 standby가 이를 replay하는 방식으로 동작한다. 일반 read replica의 목표는 primary를 최대한 빨리 따라잡는 것이다. 반대로 delayed replica는 recovery_min_apply_delay를 사용해 commit record 적용을 의도적으로 늦춘다.
PostgreSQL 문서에 따르면 이 지연은 트랜잭션 commit record에 적용된다. 예를 들어 지연을 5분으로 설정하면 standby는 primary의 commit timestamp보다 standby 시간이 최소 5분 지난 뒤 그 commit을 보이게 한다. 다른 WAL record는 먼저 replay될 수 있지만, MVCC visibility 규칙 때문에 commit record가 적용되기 전까지 사용자에게 보이지 않는다.
RDS for PostgreSQL 문서는 이 기능을 다음 버전부터 지원한다고 설명한다.
- 14.19 이상
- 15.14 이상
- 16.10 이상
- 17.6 이상
RDS 문서 기준 recovery_min_apply_delay는 밀리초 단위로 설정하며 범위는 0부터 86400000까지다. 즉 최대 24시간까지 지연시킬 수 있다. 예를 들어 1시간이면 3600000, 12시간이면 43200000이다.
중요한 점은 이 기능이 “복구 시간을 없애는 마법”이 아니라는 것이다. delayed replica가 제공하는 것은 세 가지다.
- 감지 시간: 나쁜 변경이 replica에 닿기 전 알아차릴 시간
- 정지 버튼:
pg_wal_replay_pause()로 replay를 멈출 수 있는 기회 - 승격 경로: 안전한 시점의 replica를 새 primary로 promote할 수 있는 선택지
3. 최신 이슈와 연결
AWS “What’s New” 공지는 delayed read replica가 모든 RDS for PostgreSQL 제공 리전에서 사용 가능하며, 표준 RDS 가격 외 추가 기능 요금은 없다고 설명한다. 또한 잘못된 table drop이나 unintended data modification 같은 human error로부터 time buffer를 제공하고, 문제 변경이 적용되기 전 replication을 pause하고 특정 log position까지 replay한 뒤 replica를 primary로 promote할 수 있다고 요약한다.
AWS Database Blog는 전통적인 PITR이 큰 데이터베이스에서 몇 시간이 걸릴 수 있는 반면, delayed replica는 문제가 replica에 적용되기 전 promote하면 분 단위 복구 옵션이 될 수 있다고 설명한다. 예시는 12시간 delay를 둔 replica에서 위험한 DROP DATABASE가 primary에 들어간 상황을 가정한다. 운영자는 replica에서 WAL replay를 pause하고, recovery_target_lsn 같은 목표 지점을 설정한 뒤, 안전한 시점이 확인되면 promote한다.
RDS 문서에서 특히 운영자가 봐야 할 부분은 WAL 누적이다. delayed replica는 일부러 뒤처지기 때문에 적용 전 WAL을 보관해야 한다. RDS 문서는 시스템 이벤트나 rdsrepladmin credential rotation 중 delayed replica가 REPLICATION_ERROR 상태가 될 수 있고, source instance에 WAL이 쌓여 storage exhaustion으로 이어질 수 있다고 경고한다.
즉 이 기능은 “켜두면 안전해지는 옵션”이 아니다. delayed replica를 두는 순간, 우리는 새로운 운영 대상을 하나 더 만든다.
- replica lag는 정상인가, 비정상인가?
- WAL 누적으로 source storage가 위험해지지 않는가?
- replay pause 후 누가 resume 또는 promote를 결정하는가?
- 애플리케이션 connection string은 promote 후 어디를 바라보는가?
- backup/PITR, HA standby, cross-region replica와 역할이 겹치지 않는가?
4. 개발자 관점 해석
개발자는 backup을 “나중에 복구하면 되는 것”으로 생각하기 쉽다. 하지만 운영에서는 RPO와 RTO가 다르다.
- RPO: 장애 시점 기준 얼마나 많은 데이터 손실을 감수할 수 있는가
- RTO: 서비스를 다시 정상화하는 데 얼마나 오래 걸려도 되는가
PITR은 정확한 시점으로 돌아갈 수 있다는 점에서 강력하지만, 새 인스턴스 생성과 WAL replay 시간이 든다. delayed replica는 미리 떠 있는 DB라 promote가 빠를 수 있지만, delay window 밖의 사고에는 약하고, read replica 비용과 WAL 관리 비용이 든다.
그래서 delayed replica는 다음과 같은 서비스에 더 잘 맞는다.
-
잘못된 쓰기 사고가 치명적인 서비스
- 결제, 주문, 정산, 권한, 재고, 계정 상태처럼 논리적 오염이 큰 비용을 만드는 DB
-
사고 감지가 delay window 안에 가능할 만큼 관측성이 있는 서비스
- row count 급변, delete/update rate, audit log, business metric 알림이 있어야 한다.
-
promote 후 애플리케이션 전환 절차가 연습된 서비스
- DNS, secret, connection pool, migration lock, background worker 중단 순서가 정리되어 있어야 한다.
반대로 다음 상황에서는 기대를 낮춰야 한다.
- 나쁜 쓰기를 몇 시간 뒤에야 발견한다.
- replica promote 후 애플리케이션을 어디로 붙일지 모른다.
- 모든 write path가 멱등하지 않아 복구 후 재처리 충돌이 난다.
- WAL/storage 알림이 없어 replica가 지연되는 동안 primary storage가 찬다.
delayed replica의 본질은 DB 기능이 아니라 incident response 프로세스다. “몇 시간 delay를 둘까?”보다 먼저 “그 시간 안에 누가 감지하고, 멈추고, 검증하고, 전환할까?”를 설계해야 한다.
5. 내 프로젝트에 적용할 체크포인트
작은 팀이라면 바로 delayed replica를 켜기 전에 아래 질문으로 판단해보자.
복구 목표
- 이 DB의 허용 가능한 RPO/RTO는 얼마인가?
- PITR만으로 복구하면 실제로 몇 분/몇 시간이 걸리는지 측정했는가?
- 잘못된 쓰기 사고를 보통 몇 분 안에 감지할 수 있는가?
delay window
- 15분, 1시간, 6시간, 12시간 중 어떤 window가 비즈니스 리스크와 비용에 맞는가?
- delay가 너무 짧아 사고 감지 전에 replay되어버리지는 않는가?
- delay가 너무 길어 replica의 read 용도나 WAL storage 비용을 망치지는 않는가?
관측성
- delete/update row count 급증 알림이 있는가?
- 중요한 테이블의 row count, 총액, 상태별 건수, audit event를 대시보드로 볼 수 있는가?
- replica replay 상태, lag, source storage free space,
REPLICATION_ERROR를 alert로 받고 있는가?
권한과 runbook
- 누가
pg_wal_replay_pause()를 실행할 수 있는가? - pause 후 누가 안전한 LSN/time/xid를 결정하는가?
- promote 이후 기존 primary를 어떻게 격리하고 이름을 바꾸는가?
- background worker, cron, queue consumer는 복구 중 중단되는가?
비용과 역할 분리
- 이 replica는 read scaling용인가, DR용인가? 둘을 섞으면 장애 때 판단이 흐려진다.
- HA standby, cross-region replica, automated backup, manual snapshot, delayed replica의 역할을 표로 나눴는가?
- delayed replica 비용이 사고 1회 복구 비용보다 작은가?
6. 오늘 10분 액션
오늘 바로 할 수 있는 실험은 “복구 목표 표”를 만드는 것이다.
- 운영 DB 하나를 고른다.
- 최근 30일 안에 가장 위험했던 쓰기 작업 3개를 적는다.
- 대량 삭제
- schema migration
- batch correction
- 관리자 수동 수정
- 각 작업이 실패했을 때 감지까지 걸릴 시간을 추정한다.
- 현재 PITR 복구 예상 시간을 적는다. 모르면 staging에서 실제 restore drill을 한 번 예약한다.
delay window = 감지 시간 + 의사결정 시간 + 안전 여유로 초안을 만든다.- delayed replica가 필요 없다고 결론 나더라도, “왜 PITR만으로 충분한지”를 문서로 남긴다.
작은 팀의 목표는 멋진 DR 아키텍처가 아니라, 사고 당일에 당황하지 않는 선택지를 미리 만드는 것이다.
7. 더 볼 자료
- AWS Database Blog: Using delayed read replicas for Amazon RDS for PostgreSQL disaster recovery
- Amazon RDS Docs: Configuring delayed replication with RDS for PostgreSQL
- AWS What’s New: Amazon RDS for PostgreSQL now supports delayed read replicas
- PostgreSQL 17 Docs:
recovery_min_apply_delay - Amazon RDS for PostgreSQL Release Notes
중복 회피 메모
로컬 content/generated와 Supabase의 최근 infra_dev 글을 확인했다. 최근 글은 GitHub secret scanning triage, Vercel AI Gateway routing/fallback, GitHub Actions pull_request_target 보안, OIDC subject/audience, Kubernetes Indexed Job 실패 예산, CI 네트워크 failover, EventBridge logging, Lambda durable functions, Cloudflare Queues backlog/DLQ, PostgreSQL I/O 관측을 다뤘다. 이번 글은 기존 PostgreSQL 성능 관측이나 큐/워커 재시도가 아니라, RDS for PostgreSQL delayed read replica와 PostgreSQL recovery_min_apply_delay를 바탕으로 “논리적 데이터 오염을 감지 시간 안에 멈추고 되감는 DR runbook”에 집중해 중복을 피했다.
핵심 출처
로그인하면 이 글을 북마크하고, 나만 보는 한 줄 메모를 남길 수 있어요.
댓글 0
최신순 ▾혹시 이 글을 읽는 동료 개발자가 있다면, GitHub으로 로그인하고 한 줄 흔적을 남겨줘요. (스팸 방지용 로그인이에요)