본문 바로가기
C.W.K.
Stream
Lesson 06 of 10 · published

Production 마이그레이션 — Zero-Downtime

~14 min · migrations, production, deploys

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

돌고 있는 앱을 안 깨는 schema 변경

schema 변경은 대부분 — ADD COLUMN이나 CREATE INDEX 같은 건 — 돌고 있는 SQLite DB에 그냥 적용해도 안전해. 위험한 쪽은 따로 있어. DROP COLUMN, 타입 변경, 큰 테이블 재작성은 더 신경 써야 해.

  • 더하기만 하는 변경 — DEFAULT를 단 ADD COLUMN, CREATE INDEX, CREATE TABLE. 앱이 뜰 때 적용하면 락이 잠깐 걸리고 끝나.
  • 이름 바꾸기 — 요즘 SQLite에서는 metadata만 손대는 빠른 작업이야.
  • 부수는 변경 — DROP COLUMN이나 CTAS로 타입을 바꾸는 것 말이야. 옛 코드가 아직 살아 있는 동안 안전하게 넘어가려면 순서를 지켜. 새 컬럼을 더하고, 양쪽에 다 쓰는 코드를 배포하고, 기존 데이터를 채우고, 새 컬럼을 읽는 코드를 배포하고, 그다음에 옛 컬럼을 떼어내.
  • 거대한 테이블에 인덱스 만들기 — 만드는 동안 락이 걸려. 트래픽이 적은 시간대로 잡거나, WHERE를 단 partial 인덱스로 인덱스에 담을 row 자체를 줄여(track 5에서 다뤄).
Warning: Postgres와 달리 SQLite는 인덱스를 동시에 만드는 걸 지원하지 않아. row가 1억 개인 테이블에 CREATE INDEX를 걸면 그동안 write 락이 잡혀. 미리 계산해둬. 사본에서 먼저 시간을 재보고, 필요하면 점검 시간에 배포해.

Code

안전 마이그레이션 패턴 — phased deploy·sql
-- Phase 1: additive, 마이그레이션 deploy, 양쪽 쓰는 코드 deploy
ALTER TABLE users ADD COLUMN email_lc TEXT;
UPDATE users SET email_lc = lower(email);   -- backfill
CREATE INDEX idx_users_email_lc ON users(email_lc);
PRAGMA user_version = 7;

-- Phase 2 (다음 deploy): 코드가 email_lc read
-- Phase 3 (이후 deploy): 옛 컬럼 또는 trigger drop
--   ALTER TABLE users DROP COLUMN email;

External links

Exercise

기존 schema에서 timestamp 컬럼의 저장 타입을 TEXT에서 INTEGER로 바꾸는 무중단 마이그레이션을 계획해봐. 세 단계로 써. 더하기, 양쪽 쓰기, 전환. writer가 도는 staging DB에서 순서대로 돌려보고 row가 하나도 안 사라졌는지 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.