KoderKoder.ai
가격엔터프라이즈교육투자자용
로그인시작하기

제품

가격엔터프라이즈투자자용

리소스

문의하기지원교육블로그

법적 고지

개인정보 처리방침이용 약관보안허용 사용 정책악용 신고

소셜

LinkedInTwitter
Koder.ai
언어

© 2026 Koder.ai. All rights reserved.

홈›블로그›확장/축소(Expand/Contract) 패턴으로 무중단 스키마 변경
2025년 8월 31일·5분

확장/축소(Expand/Contract) 패턴으로 무중단 스키마 변경

확장/축소(expand/contract) 패턴으로 무중단 스키마 변경을 배우세요: 안전하게 컬럼을 추가하고, 배치로 백필하고, 호환되는 코드를 배포한 뒤 오래된 경로를 제거하는 방법입니다.

확장/축소(Expand/Contract) 패턴으로 무중단 스키마 변경

스키마 변경이 왜 장애를 일으키는가

데이터베이스 변경으로 발생하는 다운타임은 항상 깔끔하고 명확한 장애로 드러나지 않습니다. 사용자 입장에서는 페이지가 무한히 로딩되거나 결제 실패가 발생하거나 앱이 갑자기 "문제가 발생했습니다"를 보여줄 수 있습니다. 팀 입장에서는 알림, 증가하는 에러율, 그리고 정리해야 할 실패한 쓰기 작업들의 쌓임으로 드러납니다.

스키마 변경이 위험한 이유는 데이터베이스가 앱의 모든 실행 버전과 공유된다는 점입니다. 릴리스 중에는 구버전과 신버전 코드가 동시에 살아 있는 경우가 많습니다(롤링 배포, 여러 인스턴스, 백그라운드 잡). 언뜻 맞아 보이는 마이그레이션도 그 중 하나의 버전을 깨트릴 수 있습니다.

일반적인 실패 사례는 다음과 같습니다:

  • 새 코드가 아직 없는 컬럼에 쓰기를 시도해 즉시 오류가 발생함.
  • 구 코드가 마이그레이션으로 이름이 바뀌었거나 삭제된 컬럼/테이블을 읽어 배포 이후 충돌이 발생함.
  • 백필이나 인덱스 생성이 CPU를 급증시키거나 행을 잠가 정상 요청이 느려지거나 타임아웃 발생.
  • NOT NULL 같은 제약을 급히 바꾸면 테이블 검사 때문에 쓰기가 블록될 수 있음.

코드 자체가 괜찮더라도 릴리스가 차단되는 진짜 문제는 타이밍과 버전 간 호환성입니다.

무중단 스키마 변경의 핵심 규칙은 하나입니다: 중간 상태들 각각이 구버전과 신버전 모두에 대해 안전해야 한다는 것. 데이터베이스를 기존 읽기/쓰기를 깨지 않고 바꾸고, 두 형태를 모두 처리할 수 있는 코드를 배포한 뒤 아무도 구 경로를 참조하지 않을 때만 구 경로를 제거하세요.

실제 트래픽이 많거나 엄격한 SLA, 그리고 많은 앱 인스턴스와 워커가 있다면 그만한 노력이 값어치가 있습니다. 반면 조용한 내부 도구라면 계획된 유지보수 창이 더 간단할 수 있습니다.

확장/축소 패턴을 쉽게 설명하면

대부분의 데이터베이스 관련 사고는 앱이 데이터베이스가 즉시 바뀔 거라고 기대하는 동안 실제 데이터베이스 변경은 시간이 걸리기 때문에 발생합니다. 확장/축소 패턴은 위험한 변경 하나를 더 작고 안전한 단계들로 나누어 이 문제를 피합니다.

짧은 기간 동안 시스템은 두 가지 "방식"을 동시에 지원합니다. 먼저 새 구조를 도입하고, 구 구조는 계속 유지하며 데이터를 점진적으로 옮긴 뒤 정리합니다.

패턴은 단순합니다:

  • 확장(Expand): 현재 앱을 깨뜨리지 않으면서 필요한 것들(컬럼, 테이블, 인덱스)을 추가합니다.
  • 둘 다 운영(Run both paths): 구 구조와 새 구조 모두 동작하도록 하는 코드를 배포해 혼합된 버전에서도 문제없게 합니다.
  • 축소(Contract): 모든 것이 새 구조를 사용하면 구 스키마와 구 코드를 제거합니다.

이 방식은 롤링 배포와 잘 어울립니다. 예를 들어 서버 10대를 하나씩 업데이트할 때 구버전과 신버전이 잠깐 같이 돌아가게 되는데, 확장/축소는 이 중첩 기간 동안 동일한 데이터베이스에서 둘 다 호환되도록 합니다.

롤백도 덜 두렵습니다. 새 릴리스에 버그가 있으면 데이터베이스를 롤백하지 않고 앱만 롤백할 수 있습니다. 왜냐하면 확장 창 동안 구 구조가 여전히 존재하기 때문입니다.

예시: PostgreSQL의 full_name 컬럼을 first_name과 last_name으로 분리하고 싶다면, 새 컬럼을 추가(확장)하고, 구·신 양쪽 형태를 읽고 쓸 수 있는 코드를 배포한 뒤 오래된 행을 백필하고, 아무도 full_name을 사용하지 않는다고 확신되면 full_name을 삭제(축소)합니다.

보통 확장 단계에서 하는 일

확장 단계의 목표는 기존 것을 제거하는 것이 아니라 새 옵션을 추가하는 것입니다.

가장 흔한 첫 번째 움직임은 새 컬럼을 추가하는 것입니다. PostgreSQL에서는 보통 NULL 허용하고 기본값 없이 추가하는 것이 가장 안전합니다. NOT NULL이나 기본값을 바로 추가하면 Postgres 버전과 변경 내용에 따라 테이블 재작성이나 더 무거운 락을 유발할 수 있습니다. 안전한 순서는: NULL 허용으로 추가 → 관대한 코드 배포 → 백필 → 나중에 NOT NULL 적용입니다.

인덱스도 주의가 필요합니다. 일반 인덱스 생성은 예상보다 더 오래 쓰기를 막을 수 있습니다. 가능하면 동시(concurrent) 인덱스 생성을 사용해 읽기/쓰기 흐름을 유지하세요. 시간이 더 걸리지만 릴리스를 멈추는 락을 피할 수 있습니다.

확장은 새 테이블을 추가하는 것을 의미할 수도 있습니다. 단일 컬럼에서 다대다 관계로 옮긴다면 조인 테이블을 추가하면서 기존 컬럼을 유지할 수 있습니다. 구 경로는 작동을 계속하고 새 구조가 데이터를 모으기 시작합니다.

실무에서 확장에는 보통 다음이 포함됩니다:

  • 기존 옆에 새 NULL 허용 컬럼이나 새 테이블 추가
  • 가능한 경우 비차단 방식으로 인덱스 추가
  • 기능 플래그로 새 읽기/쓰기 전환을 제어
  • 필요하면 구·신 필드에 둘 다 쓰기(dual-write)
  • 읽기는 하위 호환 유지(구, 신, 폴백)

확장 후에는 구버전과 신버전 앱이 동시에 놀랄 일 없이 돌아가야 합니다.

호환성을 유지하는 코드 배포

대부분의 릴리스 문제는 중간에서 발생합니다: 일부 서버는 새 코드, 일부는 구 코드가 실행되는 동안 데이터베이스는 이미 변하고 있는 상황입니다. 목표는 명확합니다: 롤아웃 중 어떤 버전이라도 구 스키마와 확장된 스키마 둘 다에서 동작해야 합니다.

일반적인 접근법은 듀얼-라이트입니다. 새 컬럼을 추가하면 새 앱은 구 컬럼과 새 컬럼 둘 다에 쓰기합니다. 구 버전은 계속 구 컬럼만 쓰고, 이는 컬럼이 여전히 존재하므로 괜찮습니다. 새 컬럼은 처음에 옵션으로 두고 모든 라이터가 업그레이드될 때까지 엄격한 제약은 미룹니다.

읽기는 보통 쓰기보다 더 신중하게 전환합니다. 당분간은 완전히 채워진 구 컬럼을 유지하다가 백필과 검증이 끝나면 새 컬럼을 우선으로 읽되 새값이 없으면 구값으로 폴백하게 하세요.

API 출력 형식도 데이터베이스가 밑에서 바뀌는 동안 안정적으로 유지하세요. 내부 필드를 추가하더라도 모든 소비자(웹, 모바일, 통합)가 준비될 때까지 응답 형태를 바꾸지 마십시오.

롤백 친화적인 롤아웃은 보통 이렇게 보입니다:

  • 릴리스 1: 새 컬럼을 추가하고 구 데이터를 읽으며 둘 다에 쓰는 코드 배포
  • 릴리스 2: 기존 행 백필 후 새 컬럼을 우선 읽되 폴백 가능한 코드 배포
  • 릴리스 3: 구 컬럼에 쓰기를 중단(컬럼은 유지)
  • 릴리스 4: 구 읽기를 제거한 뒤 구 컬럼 삭제

핵심은 구 구조를 제거하는 순간이 되돌릴 수 없는 첫 단계가 되도록 끝까지 미루는 것입니다.

DB에 과부하를 주지 않는 안전한 백필

작은 배치로 백필하기
간단한 백필 잡을 만들고 배치 크기를 조정해 팀 속도를 늦추지 마세요.
무료 사용해보기

많은 "무중단 스키마 변경"이 실패하는 지점은 바로 백필입니다. 기존 행을 새로운 컬럼으로 채우면서 긴 락, 느린 쿼리, 예상치 못한 부하 급증을 피해야 합니다.

배치가 중요합니다. 배치는 빠르게(초 단위, 분이 아닌) 끝나도록 하세요. 각 배치가 작으면 작업을 일시중지, 재개, 조정하기 쉬워 릴리스를 막지 않습니다.

진행 상황을 추적하려면 안정적인 커서가 필요합니다. PostgreSQL에서는 보통 기본 키를 사용합니다. id 순으로 행을 처리하고 마지막으로 완료한 id를 저장하거나 id 범위로 작업하세요. 이렇게 하면 작업 재시작 시 비용이 큰 전체 테이블 스캔을 피할 수 있습니다.

간단한 패턴 예시는 다음과 같습니다:

UPDATE my_table
SET new_col = ...
WHERE new_col IS NULL
  AND id > $last_id
ORDER BY id
LIMIT 1000;

업데이트에 조건(WHERE new_col IS NULL)을 두어 작업이 멱등(idempotent)하게 만드세요. 재실행은 여전히 필요한 행만 건드리므로 불필요한 쓰기를 줄입니다.

백필 중에 새 데이터가 들어오는 것을 대비하세요. 보통 순서는 다음과 같습니다:

  • 먼저 애플리케이션 코드를 업데이트해 새 쓰기도 새 필드를 채우도록 함
  • 과거 행을 작은 배치로 백필
  • 짧은 캐치업 루프로 최근 행을 재검사
  • 필요하면 트리거나 기본값 같은 가드레일을 추가해 새 NULL이 생기지 않도록 방지

좋은 백필은 지루해야 합니다: 꾸준하고 측정 가능하며 DB가 뜨거워지면 쉽게 일시정지할 수 있어야 합니다.

마이그레이션이 정말 끝났는지 검증하기

가장 위험한 순간은 새 컬럼을 추가하는 순간이 아니라 그 컬럼을 의존할 수 있다고 판단하는 순간입니다.

축소 단계로 넘어가기 전에 두 가지를 증명하세요: 새 데이터가 완전하고, 프로덕션에서 안전하게 읽히고 있다는 것.

빠르고 반복 가능한 완전성 체크로 시작하세요:

  • 새 컬럼에 예상치 못한 NULL이 없는지 확인
  • 채워야 할 행 수 대비 채워진 행 수 비교
  • 몇몇 ID를 표본 추출해 구값과 새값 비교
  • 빈 문자열, 0, 아주 오래된 레코드 같은 엣지 케이스 테스트
  • 같은 체크를 나중에 반복해 값이 흐르지 않았는지 확인

듀얼-라이트를 쓰고 있다면 무언의 버그를 잡기 위해 일관성 체크를 추가하세요. 예를 들어 old_value <> new_value인 행을 시간별로 조회해 0이 아니면 경고하도록 하면 어떤 라이터가 여전히 구 컬럼만 업데이트하는지 빠르게 발견할 수 있습니다.

마이그레이션이 실행되는 동안 기본 프로덕션 지표를 모니터링하세요. 쿼리 시간이나 락 대기가 급증하면, 안전하다고 생각한 검증 쿼리조차 부하를 더할 수 있습니다. 특히 배포 직후 새 컬럼을 읽는 코드 경로의 에러율을 주시하세요.

두 경로를 얼마나 오래 유지해야 할까요? 적어도 하나의 완전한 릴리스 사이클과 백필 재실행 하나를 견딜 만큼이면 충분합니다. 많은 팀이 1~2주를 사용하거나 구버전 앱 인스턴스가 완전히 사라졌다고 확신할 때까지 기다립니다.

축소 단계: 구 경로 제거

축소는 팀이 긴장하는 단계인데, 왜냐하면 되돌릴 수 없는 것처럼 느껴지기 때문입니다. 확장을 잘 해뒀다면 축소는 대부분 정리 작업이고 작은, 저위험 단계로 나눠 진행할 수 있습니다.

시점을 신중히 고르세요. 백필이 끝난 직후에 바로 삭제하지 마세요. 적어도 한 번의 릴리스 사이클을 더 지나게 해서 지연된 잡과 엣지 케이스가 드러날 시간을 주세요.

안전한 축소 순서는 보통 다음과 같습니다:

  • 듀얼-라이트 중단하고 새 컬럼으로만 쓰기가 이뤄지는지 확인
  • 애플리케이션에서 구 읽기 제거해 폴백 없앰
  • 구 스키마를 참조하는 죽은 코드 경로, 기능 플래그, 백그라운드 잡 제거
  • 임시 트리거, 동기화 잡, 호환성 뷰 제거
  • 구 인덱스와 제약을 제거한 뒤 구 컬럼 삭제

가능하면 축소를 두 개의 릴리스로 나누세요: 첫 번째 릴리스에서 코드 참조를 제거(추가 로깅 포함)하고, 나중에 데이터베이스 객체를 삭제합니다. 이렇게 하면 롤백과 문제 해결이 훨씬 쉬워집니다.

PostgreSQL의 세부 사항도 중요합니다. 컬럼 삭제는 대개 메타데이터 변경이지만 잠시 ACCESS EXCLUSIVE 락이 필요합니다. 조용한 시간을 계획하고 마이그레이션을 빠르게 유지하세요. 추가한 인덱스가 있다면 DROP INDEX CONCURRENTLY로 제거해 쓰기 차단을 피하세요(이 명령은 트랜잭션 블록 내부에서 실행할 수 없으므로 마이그레이션 툴이 이를 지원해야 합니다).

흔히 빠지는 실수와 트랩

안전한 스키마 변경 계획하기
생산 환경에 손대기 전에 확장-축소 플랜을 구체적인 작업과 체크포인트로 바꾸세요.
무료로 시작

무중단 마이그레이션이 실패하는 이유는 데이터베이스와 앱이 허용되는 상태에 대해 동의하지 못할 때입니다. 패턴은 중간 상태가 구 코드와 새 코드 모두에 안전할 때만 작동합니다.

프로덕션을 망가뜨리는 흔한 실수

자주 보이는 오류들은 다음과 같습니다:

  • 구버전 앱이 여전히 새 필드 없이도 쓰기를 하는 동안 NOT NULL을 너무 빨리 추가함
  • 거대한 테이블을 한 트랜잭션으로 백필해 락을 걸고 테이블 부풀음과 타임아웃을 일으킴
  • 기본값이 무료라고 가정함. PostgreSQL에서는 일부 기본값이 테이블 재작성을 유발함
  • 쓰기가 안정적으로 새 컬럼을 채우기 전에 읽기를 새 컬럼으로 전환함
  • 크론 잡, 워커, 익스포트, 리포팅 쿼리 등 다른 라이터와 리더를 잊음

현실적인 시나리오: API에서 full_name을 쓰기 시작했지만 사용자를 생성하는 백그라운드 잡은 여전히 first_name과 last_name만 설정합니다. 그 잡이 야간에 실행되어 full_name = NULL인 행을 넣고, 이후 코드가 full_name이 항상 존재한다고 가정하면 문제가 발생합니다.

마이그레이션 도중에 꼼짝 못하게 되는 상황을 피하는 법

각 단계를 며칠 동안 실행될 수 있는 릴리스처럼 취급하세요:

  • 전환 기간 동안 새 컬럼은 NULL 허용으로 두고, 먼저 코드에서 필수여부를 체크하세요.
  • 작은 배치로 백필하고 중간에 일시중지하며 DB 부하를 관찰하세요.
  • 코드를 관대하게 만드세요: 양쪽 경로를 읽고, 필요하면 둘 다 쓰며, 누락된 값을 처리하세요.
  • 테이블을 건드리는 모든 지점을 감사하세요(워커, 리포트 포함).

각 릴리스 전 빠르게 확인할 체크리스트

반복 가능한 체크리스트는 한 데이터베이스 상태에서만 동작하는 코드를 배포하는 실수를 막아줍니다.

배포 전에 데이터베이스에 확장된 요소들(새 컬럼/테이블, 낮은 락 방식으로 생성된 인덱스)이 이미 존재하는지 확인하세요. 그리고 앱이 관대하게 동작하는지(구 형태, 확장된 형태, 반쯤 백필된 상태 모두 견딜 수 있는지) 확인하세요.

짧은 체크리스트 예시는 다음과 같습니다:

  • 확장이 되어 있음: 새 스키마 객체가 존재하고 낮은 락 방식으로 추가됨
  • 호환성 존재: 앱이 구·확장 스키마 모두로 동작함(워커와 관리자 경로 포함)
  • 백필 통제됨: 작은 배치, 일시중지 가능, 기본 진행 지표 존재
  • 읽기 전환 계획 있음: 언제 읽기를 바꿀지, 결과가 이상하면 어떻게 롤백할지 명확함
  • 축소는 지연: 구 객체 삭제는 최소 1~2개 릴리스 후에 수행

마이그레이션은 읽기가 새 데이터를 사용하고, 쓰기가 더 이상 구 데이터를 유지하지 않으며, 최소한 하나의 간단한 체크(카운트나 샘플링 등)로 백필을 검증했을 때 완료로 간주합니다.

현실적인 예: 컬럼을 무중단으로 교체하기

생성된 소스 내보내기
마이그레이션 워크플로가 설정되면 생성된 소스 전체를 내보내 소유권을 유지하세요.
코드 내보내기

예를 들어 customers 테이블의 phone 컬럼이 제각각의 형식으로 저장되거나 간혹 비어있다고 합시다. 이를 phone_e164로 교체하고 싶은데 릴리스 중 차단을 허용할 수 없습니다.

깨끗한 확장/축소 순서는 다음과 같습니다:

  • 확장: phone_e164를 NULL 허용, 기본값 없음으로 추가
  • 호환 배포: 코드가 phone과 phone_e164 둘 다에 쓰도록 업데이트하되, 사용자에게는 변화가 없게 읽기는 phone을 유지
  • 백필: 기존 행을 작은 배치(예: 1,000개씩)로 변환
  • 읽기 전환: phone_e164를 우선 읽고 NULL이면 phone으로 폴백하는 코드 배포
  • 축소: 모든 것이 phone_e164를 사용하면 폴백을 제거하고 phone을 삭제한 뒤 필요한 제약을 추가

각 단계가 하위 호환성을 지키면 롤백이 단순해집니다. 읽기 전환이 문제를 일으키면 앱을 롤백하면 되고, 백필이 부하를 일으키면 작업을 일시중지하거나 배치 크기를 줄이고 재개하면 됩니다.

팀 정렬을 쉽게 하려면 계획(정확한 SQL, 어느 릴리스에서 읽기를 전환할지, 완료를 측정하는 방법, 각 단계의 책임자)을 한 곳에 문서화하세요.

다음 단계: 반복 가능한 프로세스로 만들기

확장/축소는 루틴처럼 느껴질 때 가장 잘 작동합니다. 팀이 스키마 변경마다 재사용할 수 있는 짧은 런북을 만드세요. 한 페이지 정도로 간결하되 신규 팀원이 따라할 수 있을 정도로 구체적이면 좋습니다.

실용적 템플릿 항목 예시:

  • 확장(정확한 마이그레이션 명세)
  • 코드 변경(어떤 부분이 하위 호환되어야 하고, 어디에서 듀얼-리드/듀얼-라이트를 사용하는지)
  • 백필(배치 크기, 속도 제한, 일시중지/재개 방법)
  • 검증(정확성을 증명할 쿼리와 메트릭)
  • 축소(무엇을 언제 제거할지)

사전 소유권을 정하세요. "모두가 누군가가 축소를 할 거라고 생각했다"는 말이 오래된 컬럼과 기능 플래그가 몇 달 동안 남는 원인입니다.

온라인에서 백필을 돌리더라도 트래픽이 적은 시간을 선택하세요. 배치를 작게 유지하고 DB 부하를 보며 빠르게 멈추기 쉽습니다.

Koder.ai(koder.ai)로 빌드하고 배포한다면 Planning Mode는 프로덕션에 손대기 전에 단계와 체크포인트를 정리하는 데 유용합니다. 호환성 규칙은 동일하게 적용되지만, 미리 단계를 적어두면 장애를 막는 "지루한" 단계들을 건너뛰기 어려워집니다.

자주 묻는 질문

Why do schema changes cause outages even when the SQL looks correct?

데이터베이스는 앱의 모든 실행 버전이 공유해서 사용합니다. 롤링 배포나 백그라운드 잡이 있는 동안 구버전과 신버전 코드가 동시에 돌아가므로, 이름을 바꾸거나 컬럼을 제거하거나 제약을 추가하는 마이그레이션이 특정 버전에서는 실패를 일으킬 수 있습니다.

What does “zero-downtime schema change” really mean?

중간 상태의 데이터베이스가 구버전과 신버전 코드 모두에서 동작하도록 마이그레이션을 설계한다는 뜻입니다. 먼저 새로운 구조를 추가하고, 일정 기간 두 가지 경로를 병행 운영한 뒤 아무도 구 구조에 의존하지 않을 때 구 구조를 제거합니다.

What’s the difference between the expand and contract phases?

확장은 기존 앱이 필요로 하는 것을 제거하지 않고 새 컬럼, 테이블, 인덱스 등을 추가하는 단계입니다. 축소는 새 경로가 안정적으로 작동함을 증명한 뒤 구 컬럼과 구 읽기/쓰기 경로, 동기화 로직 등을 정리하는 단계입니다.

What’s the safest way to add a new column in PostgreSQL?

대부분의 경우 기본값 없이 NULL 허용 컬럼을 추가하는 것이 가장 안전합니다. 이렇게 하면 테이블 재작성이나 무거운 락을 피할 수 있습니다. 이후 코드에서 컬럼이 없거나 NULL인 상황을 견딜 수 있게 배포하고, 점진적으로 백필한 뒤 나중에 NOT NULL 같은 제약을 적용하세요.

When should I use dual-write, and what does it do?

전환 기간 동안 새 앱이 구 필드와 새 필드 둘 다에 쓰기하는 방식입니다. 구 버전의 인스턴스나 잡이 여전히 구 필드만 쓰더라도 데이터 일관성이 유지됩니다.

How do I backfill data without slowing down production?

짧은 시간 내에 끝나는 작은 배치로 백필하세요. 각 배치는 재실행해도 안전(idempotent)해야 하며, 재시작 시 이미 처리된 행은 다시 건드리지 않도록 조건을 두세요. 쿼리 시간, 락 대기, 복제 지연 등을 모니터링하고 DB 부하가 올라가면 중단하거나 배치 크기를 줄이세요.

How can I verify the migration is actually done before dropping anything?

새 컬럼에 NULL이 남아있지 않은지 확인하고, 채워야 할 행 수 대비 채워진 수를 비교하세요. 샘플 ID를 골라 구값과 새값을 비교해보고, 빈 문자열이나 0 같은 엣지 케이스도 점검하세요. 듀얼-라이트를 사용 중이면 old_value <> new_value 같은 일관성 체크를 주기적으로 돌려 이상을 알리세요.

What are the most common migration steps that break production?

NOT NULL을 너무 일찍 추가하거나, 대량의 백필을 한 트랜잭션으로 처리해 락이나 테이블 부푼(bloat)이 생기면 문제가 됩니다. 기본값이 테이블 재작성을 유발하는 경우도 있으니 주의하세요. 또한 읽기를 새 컬럼으로 전환하기 전에 쓰기가 안정적으로 새 컬럼을 채우는지 확인해야 합니다.

When is it safe to do the contract step and drop the old column?

구 필드 쓰기를 중단하고 읽기도 새 필드만 보도록 바꾼 뒤, 충분한 릴리스 사이클(예: 1~2주) 동안 모니터링하세요. 롤아웃과 백필을 한 번 더 돌려 지연 잡이나 엣지 케이스를 잡을 시간을 두는 것이 안전합니다. 가능하면 코드에서 참조를 제거하는 릴리스와 데이터베이스 객체를 삭제하는 릴리스를 나누세요.

Do I always need expand/contract, or can I just take a maintenance window?

트래픽이 적고 유지보수 창을 허용한다면 단번에 마이그레이션을 해도 되지만, 실제 사용자와 여러 인스턴스, 백그라운드 작업, SLA가 있다면 확장/축소 패턴을 따르는 것이 더 안전합니다. Koder.ai의 Planning Mode에서 단계와 체크를 미리 적어두면 필수적인 단계를 건너뛰는 실수를 줄일 수 있습니다.

목차
스키마 변경이 왜 장애를 일으키는가확장/축소 패턴을 쉽게 설명하면보통 확장 단계에서 하는 일호환성을 유지하는 코드 배포DB에 과부하를 주지 않는 안전한 백필마이그레이션이 정말 끝났는지 검증하기축소 단계: 구 경로 제거흔히 빠지는 실수와 트랩각 릴리스 전 빠르게 확인할 체크리스트현실적인 예: 컬럼을 무중단으로 교체하기다음 단계: 반복 가능한 프로세스로 만들기자주 묻는 질문
공유
Koder.ai
Koder로 나만의 앱을 만들어 보세요 지금!

Koder의 힘을 이해하는 가장 좋은 방법은 직접 체험하는 것입니다.

무료로 시작데모 예약