2 min read

Blue-Green + DB 마이그레이션 안전 패턴

애플리케이션 전환과 스키마 변경을 분리해 다운타임 위험을 줄이는 단계별 전략

Blue-Green + DB 마이그레이션 안전 패턴 thumbnail

도입

애플리케이션은 Blue-Green으로 손쉽게 전환할 수 있지만 데이터베이스는 단순 스위치가 불가능하다. 스키마 변경과 데이터 변경이 함께 일어나면 롤백 전략이 없다면 배포 성공 후에도 서비스가 중단될 수 있다. 이 글은 DB 마이그레이션 안전성을 확보하기 위한 expand/contract 패턴과 전환 체크포인트를 다룬다.

Blue-Green + DB 마이그레이션 안전 패턴 커버
Wikimedia Commons 기반 무료 이미지

문제 정의

DB 동반 배포에서 장애가 반복되는 이유는 코드 전환과 데이터 전환을 분리하지 않기 때문이다.

  • 파괴적 스키마 변경을 먼저 적용해 이전 버전 앱이 즉시 깨진다.
  • 백필 작업 진행률을 모른 채 트래픽을 전환해 데이터 누락이 발생한다.
  • 롤백 시점에 양방향 호환이 없어 복구 시간이 길어진다.

해결 전략은 expand -> dual-write -> cutover -> contract 순서를 강제하는 것이다. 순서를 어기면 안전성을 보장하기 어렵다.

핵심 개념

관점설계 기준검증 포인트
스키마 단계호환 가능한 컬럼 추가구버전 앱 동작 여부
데이터 단계백필 + 검증 리포트NULL/불일치 건수
전환 단계읽기/쓰기 경로 분리 전환전환 직후 오류율
정리 단계구 컬럼 제거 시점 통제rollback 가능 시간

Blue-Green과 DB 마이그레이션을 하나의 배포 파이프라인으로 엮되, 데이터 단계는 독립적으로 모니터링해야 한다.

코드 예시 1: Expand 마이그레이션

ALTER TABLE orders
  ADD COLUMN payment_status_v2 TEXT;

CREATE INDEX CONCURRENTLY idx_orders_payment_status_v2
  ON orders (payment_status_v2);

-- 구버전 호환을 위해 기존 컬럼 유지
COMMENT ON COLUMN orders.payment_status_v2 IS 'new status field for v2 rollout';

코드 예시 2: Dual-write 애플리케이션 코드

export async function updatePaymentStatus(orderId: string, status: string) {
  await db.tx(async (trx) => {
    await trx.query(
      "UPDATE orders SET payment_status = $2, payment_status_v2 = $2 WHERE id = $1",
      [orderId, status],
    );
  });
}

아키텍처 흐름

Mermaid diagram rendering...

트레이드오프

  • dual-write는 안전하지만 쓰기 경로 복잡도와 부하가 증가한다.
  • expand/contract 기간을 길게 잡으면 리스크는 낮지만 개발 속도가 느려질 수 있다.
  • 전환 체크를 자동화하면 품질이 올라가지만 초기 파이프라인 구축 비용이 필요하다.

정리

Blue-Green 환경에서 DB 안전성은 순서 관리가 핵심이다. 스키마 호환, 백필 검증, 단계적 컷오버를 분리하면 장애 반경을 크게 줄일 수 있다.

이미지 출처

  • Cover: source link
  • License: CC BY-SA 3.0 / Author: Robert.Harker
  • Note: Wikimedia Commons 무료 라이선스 이미지를 다운로드 후 1600px 기준 JPG로 최적화했습니다.

댓글