TIL

DB 마이그레이션 적용하는 법

하얀잔디 2025. 5. 20. 16:33

DB 마이그레이션이라고 하면 흔히 "Flyway"라던가 "Liquibase" 하는 툴 얘기를 많이 한다.

 

근데 나는 실무에서 그런 거 안 썼다. 그냥, 쿼리 하나하나 수동으로 날렸고,
그게 당시엔 회사에서 추진하는 방식이었다~

 

이번 글에선 내가 실제로 어떤 방식으로 마이그레이션을 했는지,
그리고 지금 돌아보며 “이렇게도 할 수 있었겠다” 싶은 것들을 정리해본다.

 

 

상황: 구조 바뀐 테이블 + 백만 건 넘는 데이터

 

당시 맡았던 서비스에는 user, room, user_room_mapping 테이블이 있었다

  • user: 약 10만 건
  • room: 약 20만 건
  • user_room_mapping: 매핑 관계라 100~200만 건 추정

이제 여기서 room 테이블의 구조가 바뀌고,
컬럼도 몇 개 바뀌고, 기존 데이터도 옮겨야 하는 상황이 된 거다.

 

 

1. 점검창 확보

이건 무조건!
아무리 insert가 빨라도 운영 중 마이그레이션은 위험하다.

 

2. 새로운 테이블 생성

DDL 먼저 실행해서 새로운 구조의 테이블을 만든다.

3. 데이터 옮기기

한 번에 밀어넣는 건 부담스러워서
5만 건 단위로 나눠서 INSERT 했다.

 
INSERT INTO room_v2 (id, name, host_id.....)
SELECT id, name.... FROM room
WHERE ROWNUM BETWEEN 1 AND 50000;
 

물론 Oracle에선 ROWNUM BETWEEN은 안 되니까 서브쿼리 써야 했고…
뭐 여튼, 분할 Insert + 커밋 구조로 짰다.


4. 매핑 테이블 이관

이게 젤 무서웠다. 100만 건이니까.
트랜잭션이 길어지면 UNDO 공간부족 오류 날 수도 있기에

-> 관련에러 : https://zandi123.tistory.com/304


여기도 50,000 건씩 나눠서 처리


5. 검증 & 원본 백업

 

일단 건수 비교하고, 몇 개 random으로 눈으로 비교했다.
100% 완벽한 검증은 솔직히 못함. 그래도 최대한 꼼꼼히 확인했다.


6. 새 구조를 쓰도록 코드 수정

자바 코드에서 기존 room → room_v2로 교체.
JPA라서 Entity class도 바꾸고, 쿼리도 일부 변경.

 

 

 

느낀 주의사항

  1. 한 번에 INSERT 하지 말자
    → UNDO 공간 부족 or 성능저하 우려
  2. DDL, DML은 반드시 분리하고 순서를 철저히
    → CREATE → INSERT → 검증 → 코드 반영
  3. DB 락과 트랜잭션 범위는 정말 조심
    → 특히 매핑테이블 같이 건수 큰 테이블

 

 

그러다 나중에 알게 된 Flyway

 

정리하자면

  • SQL 파일로 버전 관리가 가능
  • 앱 실행 시 자동으로 마이그레이션 적용됨
  • flyway_schema_history 테이블로 이력 관리

 

 

나는 처음엔 그냥 수동으로 쿼리 날려서 마이그레이션을 했고,
그게 나쁜 방법은 아니었다.
운영환경에서의 신중함, 확인 절차를 배웠다.

하지만, 정기적으로 DB 스키마가 변경되는 팀이라면
Flyway나 Liquibase 같은 도구를 도입하는 게 확실히 효율적인 것 같다.

'TIL' 카테고리의 다른 글

Flutter 앱 아이콘 / 스플래시 이미지 적용법  (0) 2025.05.21
UNDO 공간부족 오류란  (0) 2025.05.20
fetch join vs EntityGraph  (0) 2025.05.19
LazyInitializationException  (0) 2025.05.19
Kotlin vs Java  (0) 2025.05.13