블루-그린 배포에서 마이그레이션은 애플리케이션 코드 배포 전에 별도의 단계로 실행되는 ‘마이그레이션 우선’ 전략을 따릅니다. 이는 새로운 코드가 배포되기 전에 데이터베이스 스키마가 준비되었음을 보장하며, 동시에 현재 실행 중인 기존 코드와의 호환성을 유지합니다. AWS ECS(Elastic Container Service) 태스크를 활용하여 데이터베이스 마이그레이션을 독립적으로 실행하는 방식은 격리된 환경에서 마이그레이션을 수행하고, 오류 발생 시 명확한 처리를 가능하게 합니다. 이 접근 방식은 마이그레이션에 동일한 Docker 이미지를 사용하고, 데이터베이스 변경 사항을 트래픽 서비스와 분리하며, 성공/실패 신호를 명확히 하여 호환되지 않는 코드 배포를 방지합니다. 또한, CloudWatch를 통해 로그를 수집하고 네트워크 격리를 통해 마이그레이션 중 외부 접근을 차단합니다.
PostgreSQL의 statement_timeout
은 장시간 쿼리가 자원을 무한정 소모하는 것을 방지하는 중요한 안전 기능이지만, 마이그레이션 중에는 이 타임아웃을 일시적으로 조정해야 할 필요가 있습니다. PG_STATEMENT_TIMEOUT=0
과 같이 환경 변수를 통해 마이그레이션 시에만 타임아웃을 무제한으로 설정하거나, 특정 마이그레이션 내에서 SET statement_timeout
명령어를 사용하여 세밀하게 제어할 수 있습니다. 이는 장시간이 소요되는 인덱스 생성이나 대규모 데이터 변경 작업 시 필수적입니다.
마이그레이션이 완료되면 AWS CodeDeploy가 블루-그린 배포를 조율합니다. Application Load Balancer 뒤에 두 개의 동일한 대상 그룹(블루 및 그린)을 설정하고, CodeDeploy가 이들 간의 트래픽 전환을 관리하여 문제 발생 시 즉각적인 롤백을 가능하게 합니다. Terraform을 사용하여 대상 그룹의 헬스 체크, 연결 종료 지연(deregistration delay), 그리고 이전 환경 유지 시간 등을 구성하여 안정적인 전환을 보장합니다.
프로덕션 환경에서는 다음과 같은 마이그레이션 패턴을 고려해야 합니다. 수백만 개의 행을 가진 테이블에 인덱스를 추가할 때는 테이블 전체에 잠금을 걸지 않도록 PostgreSQL의 동시 인덱스 생성(algorithm: :concurrently
) 기능을 반드시 사용해야 합니다. 마이그레이션이 부분적으로 실패할 경우를 대비하여, if_not_exists: true
나 column_exists?
와 같은 조건을 활용하여 여러 번 실행해도 안전한 멱등성(Idempotent) 마이그레이션을 작성해야 합니다. 보고 및 분석을 위한 Materialized View
는 물리적으로 쿼리 결과를 저장하여 읽기 성능을 향상시키며, REFRESH MATERIALIZED VIEW CONCURRENTLY
옵션을 사용하여 업데이트 중에도 애플리케이션이 뷰를 계속 읽을 수 있도록 합니다. 마지막으로, 웹 서버, 백그라운드 워커, 큐 프로세서 등 여러 서비스로 구성된 Rails 애플리케이션의 경우, 모든 서비스가 마이그레이션 완료를 기다리고 SIGTERM
과 같은 신호를 통해 정상적인 종료를 처리하도록 구성하여 버전 불일치를 방지하고 시스템 일관성을 유지해야 합니다.
견고한 프로덕션 배포를 위해서는 DDL 트랜잭션 비활성화, 적절한 타임아웃 설정, 동시 작업 사용, 멱등성 마이그레이션, 롤백 절차 테스트, 마이그레이션 시간 모니터링, 마이그레이션 소규모 유지, strong_migrations
gem 활용과 같은 모범 사례를 따르는 것이 중요합니다. 부분적인 마이그레이션 실패, 타임아웃, 잠금 경합 등 문제가 발생할 경우를 대비하여 복구 가능한 마이그레이션 설계 및 적절한 타임아웃/잠금 타임아웃 설정, 그리고 down
메서드의 올바른 구현을 통해 신속하게 대응할 수 있어야 합니다.