이 페이지에서 다루는 것
AI DB 마이그레이션 검증
한 번에 끝까지 읽으며 맥락을 쌓을 수 있도록 구성했습니다.
AI 에이전트가 만든 스키마 변경을 데이터 손실 없이 배포하기 위한 expand-contract, 백필, 드라이런, 롤백 기준 실전 절차
학습 유형
주제 심층 학습
핵심 주제
AI DB 마이그레이션 검증
키워드
VIBE 코딩 · DB 마이그레이션 · AI 에이전트 · 데이터 검증 · 배포 안전 · 롤백
이 페이지에서 다루는 것
AI DB 마이그레이션 검증
한 번에 끝까지 읽으며 맥락을 쌓을 수 있도록 구성했습니다.
예상 학습 시간
16분
본문과 보조 자료(이미지·영상)를 포함한 대략적인 소요입니다.
학습 팁
섹션 순서대로 읽고, 필요한 부분만 다시 찾아보기
표·이미지·영상은 본문 흐름을 돕는 보조 설명입니다.
AI 에이전트는 CRUD 코드뿐 아니라 테이블, 컬럼, 인덱스, 백필 스크립트까지 한 번에 제안합니다. 속도는 빨라지지만 데이터베이스 변경은 실패 비용이 다릅니다. UI 버그는 다시 배포하면 되지만, 잘못된 DROP, 타입 축소, 누락된 백필, 깨진 외래키는 실제 고객 데이터 손실로 이어질 수 있습니다.
이 글의 문제는 하나입니다. 'AI가 만든 DB 마이그레이션을 사람 운영자가 어떻게 검증하고 배포해야 데이터 손실을 막을 수 있는가'입니다. 답은 AI를 믿거나 금지하는 것이 아니라, AI가 낸 변경을 작은 단계와 자동 검증으로 통과시키는 가드레일을 만드는 것입니다.
AI DB 마이그레이션은 코드 변경이 아니라 데이터 변경으로 다뤄야 합니다. 안전한 기본형은 expand-contract입니다. 먼저 새 구조를 추가하고, 코드가 새 구조와 예전 구조를 동시에 읽고 쓰게 만든 뒤, 백필과 관측 지표가 안정적일 때만 예전 구조를 제거합니다.
실무 절차는 다음 순서로 고정하는 것이 좋습니다.
초보자에게는 '데이터베이스를 고칠 때 한 번에 바꾸지 말고, 새 길을 만들고, 차가 안전하게 다니는지 확인한 뒤, 옛길을 닫는 방식'이라고 이해하면 됩니다. 실무자에게는 '스키마 변경, 애플리케이션 릴리스, 백필, 관측, 제거를 서로 다른 배포 단위로 쪼개는 운영 패턴'입니다.
AI 에이전트는 요구사항을 듣고 순식간에 테이블 설계, ORM 모델, 폼, API, 테스트를 함께 만듭니다. 문제는 그럴듯한 마이그레이션이 운영 데이터의 시간성을 모를 수 있다는 점입니다. 예를 들어 문자열 컬럼을 enum으로 바꾸면 코드상으로는 깔끔하지만, 기존 데이터에 예외 값이 하나만 있어도 배포가 실패하거나 값이 잘립니다.
AI가 특히 실수하기 쉬운 지점은 다음과 같습니다.
| 위험 | 겉보기 증상 | 실제 사고 |
|---|---|---|
| 파괴적 변경 | DROP 컬럼이 간단해 보임 | 롤백해도 데이터가 돌아오지 않음 |
| 타입 축소 | 문자열 길이를 줄임 | 기존 값 잘림 또는 저장 실패 |
| 즉시 NOT NULL | 새 컬럼에 제약을 바로 추가 | 기존 행 때문에 마이그레이션 중단 |
| 대량 백필 | 한 번의 UPDATE로 끝내려 함 | 잠금, 타임아웃, 서비스 지연 |
| 코드와 스키마 동시 전환 | 한 커밋에 모두 포함 | 배포 순서가 바뀌면 장애 |
VIBE 코딩의 장점은 빠른 반복입니다. 그러나 DB 변경에서 빠른 반복은 '되돌릴 수 있는 작은 실험'이어야 합니다. 되돌릴 수 없는 작업을 빠르게 반복하면 생산성이 아니라 사고 발생 속도만 올라갑니다.
문법이 맞는 마이그레이션도 위험할 수 있습니다. 리뷰의 핵심 질문은 '실제 운영 데이터가 있는 상태에서 어떤 순서로 안전하게 지나갈 수 있는가'입니다. 그래서 코드 리뷰에는 역호환, 데이터 보존, 잠금 시간, 백필 재시도, 관측 지표, 롤백 기준이 함께 들어가야 합니다.
AI 에이전트에게 '사용자 프로필에 plan 컬럼을 추가해 주세요'라고만 말하면, 에이전트는 새 컬럼 추가와 기존 로직 교체를 한 번에 제안할 수 있습니다. 더 안전한 브리프는 다음 조건을 포함합니다.
이렇게 말하면 AI가 내는 결과의 모양이 달라집니다. 좋은 프롬프트는 멋진 코드를 요구하는 문장이 아니라 운영 제약을 코드 생성 조건으로 바꾸는 문장입니다.
expand는 새 구조를 추가하되 기존 구조를 깨지 않는 단계입니다. 예를 들어 user_plan 컬럼을 추가하더라도 기존 plan_text 컬럼을 삭제하지 않습니다. 새 인덱스도 가능하면 온라인 생성 또는 낮은 트래픽 시간대 적용을 고려합니다.
이 단계에서 확인할 것은 세 가지입니다. 첫째, 기존 코드가 새 스키마에서도 계속 동작하는가. 둘째, 새 코드가 배포되기 전에도 마이그레이션이 안전한가. 셋째, 마이그레이션 실패 시 재시도할 수 있는가입니다.
드라이런은 실제 운영 적용 전에 같은 종류의 데이터나 스테이징 환경에서 실행 결과를 보는 절차입니다. 스키마 diff는 현재 DB 구조와 목표 구조의 차이를 사람이 읽을 수 있게 확인하는 절차입니다. 둘은 역할이 다릅니다. 드라이런은 실행 위험을 보고, 스키마 diff는 의도하지 않은 구조 변경을 봅니다.
검토할 질문은 구체적이어야 합니다. 삭제되는 컬럼이 있는가. 인덱스 이름이 바뀌면서 기존 인덱스가 중복 생성되는가. 제약 조건 추가 순서가 기존 행을 막는가. 기본값이 모든 기존 행에 적용되는가. 마이그레이션을 두 번 실행해도 같은 결과가 되는가.
백필은 기존 데이터를 새 구조에 채우는 작업입니다. 가장 흔한 실수는 한 번의 대형 UPDATE로 끝내려는 것입니다. 작은 서비스에서는 운 좋게 지나갈 수 있지만, 운영에서는 잠금과 타임아웃을 만들 수 있습니다.
좋은 백필은 다음 성질을 가집니다.
AI 에이전트에게 백필을 맡길 때는 '전체 갱신 스크립트'가 아니라 '재실행 가능한 배치 작업'을 요구해야 합니다.
스키마가 준비됐다고 바로 모든 읽기 경로를 새 컬럼으로 바꾸면 문제가 생겼을 때 원인을 좁히기 어렵습니다. feature flag를 쓰면 새 읽기 경로를 일부 요청이나 내부 계정에만 켤 수 있습니다. 단순한 플래그가 없더라도 환경별 설정, 비율 기반 조건, 운영자만 접근 가능한 Preview 경로 같은 방식으로 전환 범위를 줄일 수 있습니다.
중요한 것은 마이그레이션 성공과 비즈니스 로직 전환을 같은 버튼으로 묶지 않는 것입니다. DB 구조 준비, 백필 완료, 새 읽기 적용, 예전 구조 제거는 서로 다른 승인 지점이어야 합니다.
배포 뒤 무엇을 볼지 정하지 않으면 '문제가 있어 보이면 되돌린다'는 애매한 판단이 됩니다. 최소한 다음 관측 지표를 준비합니다.
롤백 기준도 숫자로 두는 것이 좋습니다. 예를 들어 새 읽기 경로 활성화 후 10분 동안 관련 API 오류율이 평소보다 두 배 이상이면 feature flag를 끈다. 백필 실패율이 0.5%를 넘으면 contract 단계를 중지한다. 새 컬럼과 예전 컬럼의 값 불일치가 발견되면 예전 읽기 경로를 유지한다.
contract는 예전 구조를 제거하는 단계입니다. 많은 사고는 이 단계를 너무 빨리 하면서 발생합니다. 예전 컬럼을 삭제하면 롤백이 단순하지 않습니다. 코드를 되돌려도 데이터가 없기 때문입니다.
contract는 다음 조건을 만족할 때만 진행합니다. 새 구조가 충분한 기간 안정적으로 쓰였고, 백필 검증이 끝났고, 읽기·쓰기 경로가 완전히 전환됐고, 예전 구조를 참조하는 코드가 검색되지 않고, 백업 또는 보존 정책이 확인됐을 때입니다.
사용자 테이블에 onboarding_completed_at을 추가한다고 가정합니다. 안전한 순서는 nullable 컬럼 추가, 새 가입자부터 값 쓰기, 기존 사용자 백필, 화면에서 새 값 읽기, 일정 기간 후 필요하면 제약 조건 강화입니다. 처음부터 NOT NULL을 걸면 기존 행이 막힐 수 있습니다.
AI에게는 '새 컬럼 추가와 기존 데이터 백필을 분리하고, 기존 코드가 새 컬럼 없이도 동작하는 순서로 제안하라'고 요청합니다. 리뷰에서는 새 컬럼 기본값이 비즈니스 의미를 왜곡하지 않는지 봅니다.
status 컬럼에 paid, pending, failed뿐 아니라 과거 값인 retry, manual_check가 섞여 있을 수 있습니다. AI는 문서에 있는 세 값만 보고 enum 제약을 만들 수 있습니다. 이때 바로 제약을 걸면 운영 데이터가 깨집니다.
안전한 방식은 현재 값 분포를 먼저 집계하고, 예외 값을 매핑하거나 보존 정책을 정한 뒤, 새 status_v2 컬럼에 정규화 값을 백필하는 것입니다. 그다음 코드가 status_v2를 읽도록 전환하고, 충분히 안정된 뒤 예전 status를 제거합니다.
AI가 느린 목록 조회를 고치기 위해 인덱스를 제안할 수 있습니다. 인덱스 추가는 삭제보다 안전해 보이지만, 큰 테이블에서는 생성 시간과 쓰기 성능 영향을 봐야 합니다. 사용 DB가 온라인 인덱스 생성을 지원하는지, 인덱스 컬럼 순서가 실제 WHERE와 ORDER BY에 맞는지, 기존 중복 인덱스가 있는지 확인합니다.
이 경우 롤백은 인덱스 제거일 수 있지만, 제거도 운영 부하를 만들 수 있습니다. 그래서 낮은 트래픽 시간대 적용과 쿼리 계획 확인이 검증 체크리스트에 들어가야 합니다.
첫 번째 실수는 AI가 만든 마이그레이션 파일을 '테스트가 통과했으니 괜찮다'고 보는 것입니다. 단위 테스트는 운영 데이터 분포, 잠금 시간, 배포 순서 문제를 충분히 보여주지 못합니다. 테스트는 필요하지만 데이터 검증과 배포 설계가 함께 있어야 합니다.
두 번째 실수는 코드와 스키마를 한 배포에 강하게 묶는 것입니다. 새 코드가 새 컬럼을 반드시 필요로 하고, 예전 코드는 새 스키마에서 실패한다면 배포와 롤백 모두 어려워집니다. 역호환은 선택이 아니라 운영 안전장치입니다.
세 번째 실수는 백필 스크립트에 관측을 넣지 않는 것입니다. '완료' 로그 하나만 남기면 중간 실패, 일부 누락, 느린 처리, 예외 데이터가 보이지 않습니다. 백필에는 처리량, 남은 수, 실패 수, 샘플 검증이 있어야 합니다.
네 번째 실수는 제거 작업을 정리로 착각하는 것입니다. 사용하지 않는 컬럼 삭제는 기술 부채를 줄이지만, 너무 빠른 삭제는 복구 경로를 없앱니다. 정리는 안정화 기간 뒤에 해야 합니다.
다섯 번째 실수는 AI에게 '마이그레이션 만들어 줘'라고만 요청하는 것입니다. AI는 작업 범위가 넓을수록 한 번에 많이 고치려는 경향이 있습니다. 운영자는 금지 작업, 단계 분리, 검증 방식, 롤백 기준을 프롬프트와 리뷰 기준으로 제공해야 합니다.
배포 전에는 다음 항목을 확인합니다.
배포 후에는 새 쓰기와 예전 읽기, 예전 쓰기와 새 읽기가 모두 안전한지 샘플을 봅니다. 목록, 상세, 검색, 관리자성 내부 도구처럼 같은 데이터를 다른 경로로 읽는 화면도 함께 확인해야 합니다.
팀이나 개인 프로젝트에 바로 적용하려면 세 가지 템플릿을 만드세요. 첫째, AI 에이전트에게 주는 DB 변경 브리프입니다. 여기에는 금지 작업, 단계 분리, 백필 방식, 롤백 기준을 포함합니다. 둘째, Pull Request나 변경 요청에 붙이는 마이그레이션 리뷰 체크리스트입니다. 셋째, 배포 후 30분 동안 볼 관측 지표 목록입니다.
처음부터 완벽한 플랫폼을 만들 필요는 없습니다. 다음 DB 변경부터 '삭제 금지, 역호환, 드라이런, 백필 진행률, feature flag, 롤백 기준' 여섯 가지만 요구해도 사고 확률이 크게 줄어듭니다. VIBE 코딩에서 AI 에이전트는 속도를 담당하고, 운영자는 되돌릴 수 있는 경로를 설계합니다. 좋은 마이그레이션은 빨리 적용되는 마이그레이션이 아니라 안전하게 지나가고, 문제가 생겨도 데이터를 잃지 않는 마이그레이션입니다.
다음 학습
웹훅은 외부 시스템이 웹앱에 사건을 알려주는 입구입니다. Web Push는 브라우저가 닫혀 있거나 화면을 보고 있지 않을 때도 운영체제 알림으로 사용자를 깨우는 출구입니다. 두 기술을 연결하면 자동화 엔진, 배포 파이프라인, 모니터링, Hermes 같은 작업자가 중요한 사건을 사람의 휴대폰과 PC 브라우저로 바로 전달할 수 있습니다.
이 글은 한 가지 실전 문제를 다룹니다. '외부 서버에서 작업 완료 웹훅을 보냈을 때, 안드로이드 Chrome과 PC 브라우저에 안정적으로 푸시 알림을 띄우려면 어떤 구조로 설계해야 하는가'입니다. 단순히 알림 코드 몇 줄을 붙이는 이야기가 아닙니다. PWA, Service Worker, Web Push, VAPID, 구독 저장, 웹훅 인증, 만료 구독 정리, Telegram 같은 보조 채널, 클릭 후 상세 페이…
AI 코딩에서 위험한 순간은 코드가 만들어지는 순간보다 배포 직후입니다. 로컬 테스트와 빌드가 모두 통과해도, 실제 도메인에서는 데이터 연결, 캐시, 라우팅, 브라우저 실행 환경, 공개 문구 같은 이유로 다른 결과가 나올 수 있습니다. 그래서 AI에게 구현을 맡겼다면 배포 후에도 사람이 읽을 수 있는 검증 증거를 남겨야 합니다.
이 글은 한 가지 실전 문제를 다룹니다. 'AI가 만든 변경을 서비스에 올린 뒤 무엇을 확인해야 배포를 끝냈다고 말할 수 있는가'입니다. 답은 거창한 모니터링 체계를 새로 만드는 것이 아니라, 배포 상태, 대표 경로, 콘솔 오류, 공개 금지어, 롤백 기준을 짧고 반복 가능한 라이브 스모크 루프로 묶는 것입니다.