2 min read

Blue-Green + DB Migration Safety Pattern

Step-by-step strategy to reduce downtime risk by decoupling application transitions from schema changes

Blue-Green + DB Migration Safety Pattern thumbnail

Introduction

Applications can be easily switched from Blue to Green, but a simple switch is not possible for databases. If schema changes and data changes occur together, service may be interrupted even after successful deployment if there is no rollback strategy. This article covers expand/contract patterns and conversion checkpoints to ensure DB migration safety.

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

Problem definition

The reason why failures are repeated in DB accompanying distribution is because code conversion and data conversion are not separated.

  • Destructive schema changes are applied first, causing previous versions of the app to break immediately.
  • Data loss occurs when traffic is switched without knowing the progress of the backfill operation.
  • There is no two-way compatibility at the time of rollback, which increases recovery time.

The solution strategy is to enforce the order expand -> dual-write -> cutover -> contract. If the order is violated, it is difficult to guarantee safety.

Key concepts

perspectiveDesign criteriaVerification points
schema levelAdd compatible columnWhether the old version app works
data stepBackfill + Verification ReportNumber of NULL/mismatches
Transition StageToggle separate read/write pathsError rate immediately after conversion
Cleanup StepsControlling the timing of old column removalrollback possible time

Blue-Green and DB migration should be combined into one deployment pipeline, but the data stage should be monitored independently.

Code Example 1: Expand Migration

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';

Code example 2: Dual-write application code

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],
    );
  });
}

Architecture flow

Mermaid diagram rendering...

Tradeoffs

  • Dual-write is safe, but it increases write path complexity and load.
  • If the expand/contract period is long, the risk is low, but the development speed may slow down.
  • Automating conversion checks increases quality, but requires initial pipeline construction costs.

Cleanup

Order management is key to DB safety in a Blue-Green environment. Separating schema compatibility, backfill verification, and staged cutover can significantly reduce the failure radius.

Image source

  • Cover: source link
  • License: CC BY-SA 3.0 / Author: Robert.Harker
  • Note: After downloading the free license image from Wikimedia Commons, it was optimized to JPG at 1600px.

Comments