MMeshOps
데이터베이스 마이그레이션 실전: 다운타임 없는 안전한 DB 변경
12예상 10중급

무중단 스키마 변경 5단계 2부: 배포와 폐기

앱이 새로운 컬럼을 사용하도록 배포한 뒤, 구 컬럼의 참조를 완벽히 제거하고 데이터베이스에서 최종 삭제하는 과정을 완료합니다.

지난 시간에 우리는 새로운 컬럼을 만들고, 앱에서 양방향 쓰기를 활성화한 뒤, 과거의 데이터를 모두 백그라운드에서 복사하는 3단계까지 무사히 마쳤습니다. 현재 데이터베이스의 구 컬럼(`phone_number`)과 신 컬럼(`contact_number`)은 완벽하게 동일한 데이터를 가지고 있습니다. 이제 남은 것은 애플리케이션의 시선을 새로운 쪽으로 돌리고, 쓸모없어진 옛 흔적을 지우는 전환과 수축(Contract) 과정입니다. 끝까지 다운타임 없이 마무리하는 마지막 두 단계를 살펴봅시다.

4단계: 신규 컬럼으로 읽기 전환 배포

현재 애플리케이션은 양쪽에 데이터를 쓰고 있지만, 데이터를 읽어올 때(Read)는 여전히 구버전 컬럼을 참조하고 있습니다. 4단계의 목표는 이 읽기 로직을 새 컬럼으로 변경하고, 더 이상 필요 없어진 구 컬럼에 대한 쓰기 작업(Dual Writing)을 중단하는 것입니다.

코드의 완전한 전환

애플리케이션 코드를 열어 기존에 `phone_number`를 참조하던 모든 로직을 걷어내고, 오직 `contact_number`만 바라보도록 코드를 수정합니다.

// [3단계까지의 상태] 
// 쓰기: phone_number(O), contact_number(O)
// 읽기: phone_number(O)

// [4단계 수정 코드 - 완전한 전환]
// 사용자 정보 조회 로직
const userPhone = user.contact_number; // 신규 컬럼에서만 읽기

// 사용자 정보 저장 로직
db.users.insert({ 
  // phone_number: ... (구 컬럼 쓰기 삭제!)
  contact_number: "+821012345678"   // 신규 컬럼에만 쓰기
});

이제 애플리케이션은 구 컬럼인 `phone_number`의 존재를 코드 상에서 완벽하게 잊게 됩니다. 이 수정된 코드를 운영 서버에 배포합니다.

롤링 배포 시의 안전성 확인

이 배포 과정이 다운타임 없이 안전한지 다시 한 번 점검해 봅시다. 롤링 배포 중에는 구버전 앱과 신버전 앱이 동시에 존재합니다.

  • 구버전 앱: 여전히 양쪽에 쓰고(`Dual Writing`), 구 컬럼에서 읽습니다. 양쪽 데이터가 동기화되어 있으므로 정상 작동합니다.
  • 신버전 앱: 오직 새 컬럼에만 쓰고, 새 컬럼에서 읽습니다. 역시 데이터가 완벽하므로 정상 작동합니다.

배포가 100% 완료되면, 드디어 데이터베이스의 구 컬럼은 더 이상 어떤 트래픽도 받지 않는 완전한 잉여 자원이 됩니다. 아무도 읽지 않고, 아무도 쓰지 않습니다.

5단계: 구버전 컬럼 삭제 (Contract)

모든 애플리케이션 배포가 끝나고, 신규 로직이 안정적으로 동작하는 것을 모니터링을 통해 충분히 확인했다면 이제 마지막 단계에 돌입합니다. 바로 불필요해진 공간을 수축(Contract)시키는 과정입니다.

마지막 데이터베이스 마이그레이션 스크립트를 작성합니다.

-- 5단계: 불필요해진 구 컬럼 삭제
ALTER TABLE users DROP COLUMN phone_number;

이 스크립트를 운영 환경에서 실행합니다.

5단계에서 주의할 점

오해 또는 실수

배포 직후 바로 DROP 마이그레이션 실행하기

바로잡기

혹시라도 새 코드에 버그가 있어 롤백(Rollback)해야 할 상황에 대비해, 수일~수주의 유예 기간을 두고 충분히 관찰한 뒤 삭제하는 것이 안전합니다.

오해 또는 실수

다른 시스템의 참조 여부 무시하기

바로잡기

메인 앱 외에도 데이터 파이프라인, 분석용 배치 스크립트 등 다른 곳에서 구 컬럼을 참조하고 있지 않은지 확실히 체크한 후 삭제해야 합니다.

최종 스키마 정리 완료

`DROP COLUMN` 명령어가 성공적으로 실행되면서, 길고 길었던 무중단 스키마 변경 여정이 드디어 막을 내립니다.

사용자나 서버 입장에서는 어떤 서비스 중단이나 에러도 경험하지 못했지만, 우리 시스템 내부적으로는 수많은 데이터가 이동하고 구조가 안전하게 새 단장을 마쳤습니다. 이것이 바로 바이브코딩 시대에도 개발자와 인프라를 지탱하는 엔지니어링의 신뢰성입니다.

무중단 마이그레이션 전략의 가치

우리는 고작 컬럼 이름 하나 바꾸기 위해 5단계라는 긴 여정을 거쳤습니다. 마이그레이션 파일도 최소 2번 이상 나뉘어 작성되었고, 애플리케이션 코드 배포도 여러 번 이루어졌습니다.

마이그레이션 접근 방식 요약

방식작업 횟수장애 발생 확률권장 상황
직접 변경 (RENAME)1회매우 높음트래픽이 없는 개발 환경이나 오픈 전 극초기
점진적 변경 (5단계)여러 회 (DB/App 교차)매우 낮음 (무중단)실제 사용자가 있는 모든 운영 환경

이 과정이 비효율적으로 보일 수 있지만, 실무에서 장애 복구에 들어가는 시간과 고객 신뢰의 손실을 생각하면 이는 가장 빠르고 효율적인 지름길입니다. 파괴적인 변경을 피하고, 철저히 하위 호환성을 유지하며 시스템을 우회시키는 이 Expand and Contract 패턴은 컬럼명 변경뿐만 아니라 데이터 타입 변경, 테이블 분리 등 거의 모든 복잡한 데이터베이스 리팩토링에 똑같이 적용할 수 있는 만능 열쇠입니다.

다음 에피소드에서는 AI 코딩 도구를 사용할 때 우리가 놓치기 쉬운 마이그레이션 관련 실수들을 방지하기 위한 'AI 코드 리뷰 체크리스트'를 정리해 보겠습니다.

예시

-- 예시

개념 퀴즈

퀴즈 답을 맞춰야 학습 완료가 됩니다.

무중단 마이그레이션 4단계에서 애플리케이션 코드를 수정할 때 올바른 조치는 무엇인가요?

3줄 요약

  1. 14단계: 앱의 모든 읽기/쓰기 로직이 새로운 컬럼만 참조하도록 코드를 수정하여 배포합니다.
  2. 25단계: 새로운 시스템이 안정화된 것을 확인한 후, 아무도 사용하지 않는 구 컬럼을 DB에서 DROP하여 수축시킵니다.
  3. 3안전한 5단계 전략은 번거롭지만 서비스 중단과 고객의 신뢰 하락을 막는 가장 확실한 실무 엔지니어링 기법입니다.