DB 마이그레이션 툴

배고픈귤·2026년 5월 12일

Backend

목록 보기
11/11

DB 마이그레이션이란?

애플리케이션이 발전하면서 DB 스키마도 계속 변경된다. 협업을 하다보면 이러한 스키마 수정 값들이 제대로 반영되지 않아 문제가 발생할 수 있다.
테이블 추가, 컬럼 변경, 인덱스 추가 등의 스키마를 코드처럼 버전 관리하는 것이 DB 마이그레이션이다.

"DB 변경 이력을 Git처럼 관리하자"

수동으로 SQL을 실행하면 생기는 문제들:

  • 어떤 환경(dev/staging/prod)에 어떤 SQL이 적용됐는지 추적 불가
  • 팀원마다 DB 상태가 달라지는 문제
  • 배포 시 DB 변경 누락

SpringBoot에서 사용하는 대표적인 마이그레이션 툴 Flyway와 LiquiBase에 대해 알아보도록 하자.


1. Flyway

개념

  • SQL 파일 기반 마이그레이션 툴
  • 단순하고 직관적, 러닝커브 낮음
  • 파일 이름 규칙으로 버전 관리

파일 네이밍 규칙

V{버전}__{설명}.sql

V1__create_user_table.sql
V2__add_email_column.sql
V3__create_order_table.sql

V + 버전번호 + __(언더바 2개) + 설명 + .sql

Spring Boot 설정

build.gradle.kts

dependencies {
    implementation("org.flywaydb:flyway-core")
    implementation("org.flywaydb:flyway-mysql") // DB에 맞게
}

application.yml

spring:
  flyway:
    enabled: true
    locations: classpath:db/migration  # SQL 파일 위치
    baseline-on-migrate: true          # 기존 DB가 있을 때

파일 위치

src/main/resources/
└── db/
    └── migration/
        ├── V1__create_user_table.sql
        ├── V2__add_email_column.sql
        └── V3__create_order_table.sql

V1__create_user_table.sql

CREATE TABLE users (
    id      BIGINT AUTO_INCREMENT PRIMARY KEY,
    name    VARCHAR(100) NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

동작 방식

Flyway는 flyway_schema_history 테이블을 자동 생성해서 적용된 마이그레이션을 추적합니다.

| version | description         | installed_on        | success |
|---------|---------------------|---------------------|---------|
| 1       | create user table   | 2024-01-01 10:00:00 | true    |
| 2       | add email column    | 2024-01-02 11:00:00 | true    |

2. Liquibase

개념

  • XML / YAML / JSON / SQL 다양한 형식 지원
  • Flyway보다 기능이 풍부하고 유연함
  • changeset 단위로 변경 관리
  • 롤백(Rollback) 기능 공식 지원

Spring Boot 설정

build.gradle.kts

dependencies {
    implementation("org.liquibase:liquibase-core")
}

application.yml

spring:
  liquibase:
    enabled: true
    change-log: classpath:db/changelog/db.changelog-master.yaml

changelog 구조

src/main/resources/
└── db/
    └── changelog/
        ├── db.changelog-master.yaml   # 마스터 파일 (진입점)
        ├── 2024/
        │   ├── 01-create-user.yaml
        │   └── 02-add-email.yaml
        └── 2025/
            └── 01-create-order.yaml

db.changelog-master.yaml

databaseChangeLog:
  - include:
      file: db/changelog/2024/01-create-user.yaml
  - include:
      file: db/changelog/2024/02-add-email.yaml

01-create-user.yaml

databaseChangeLog:
  - changeSet:
      id: 1
      author: gildong
      changes:
        - createTable:
            tableName: users
            columns:
              - column:
                  name: id
                  type: BIGINT
                  autoIncrement: true
                  constraints:
                    primaryKey: true
              - column:
                  name: name
                  type: VARCHAR(100)
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: DATETIME
                  defaultValueComputed: CURRENT_TIMESTAMP
      rollback:
        - dropTable:
            tableName: users

롤백 실행

# CLI로 롤백
liquibase rollback --tag=v1.0

# 특정 changeset 수만큼 롤백
liquibase rollbackCount 2

3. Flyway vs Liquibase 비교

항목FlywayLiquibase
형식SQL 중심XML / YAML / JSON / SQL
롤백수동 작성 필요공식 지원
조건부 실행미지원지원 (preconditions)
가독성SQL 그대로라 직관적설정 파일 구조
엔터프라이즈 기능유료 플랜유료 플랜
적합한 규모소~중규모중~대규모

현재 에러 섹션을 보면 이렇게 3단계로 나뉘어 있어요.

1. 주 에러 상황 표 (원인 + 설명만)
2. 공통 + 툴별 해결법 표
3. Flyway / Liquibase 상황별 해결법 표 (2번과 중복)

2번과 3번을 합치고 1번은 제거하면 깔끔해져요. 이렇게요:


에러 상황 및 해결법

이러한 DB 마이그레이션 툴을 처음 사용하다보면 에러 상황에 직면할 때가 많다.

원인설명공통 해결법FlywayLiquibase
파일 수정이미 적용된 마이그레이션 파일을 수정체크섬 초기화 후 재적용flyway repairliquibase clearCheckSums
파일 삭제적용된 마이그레이션 파일을 삭제히스토리 테이블에서 해당 버전 기록 삭제flyway_schema_history 에서 해당 행 DELETEDATABASECHANGELOG 에서 해당 행 DELETE
수동 SQL누군가 DB에 직접 SQL 실행히스토리 테이블에 실행된 것처럼 수동 기록flyway_schema_history 에 행 INSERTliquibase changelogSync 로 자동 동기화
버전 충돌브랜치 병합 후 같은 버전 파일 충돌충돌 파일 버전 변경 후 재정렬out-of-order: true 로 순서 무시 허용changeset id 중복이 없으므로 충돌 자체가 드묾
  • Flyway — 히스토리 테이블을 직접 SQL로 조작하는 경우가 많다
  • LiquibasechangelogSync, clearCheckSums전용 명령어로 대부분 해결할 수 있다

추가로 아래는 각 툴에서만 발생하는 케이스다.

Flyway 추가 케이스

상황해결법
실패한 마이그레이션 잔존flyway_schema_history에서 success = false 행 삭제 후 재실행
기존 DB에 처음 도입baseline-on-migrate: true 설정

Liquibase 추가 케이스

상황해결법
특정 시점으로 되돌리기미리 작성한 rollback 태그로 liquibase rollback
기존 DB에 처음 도입liquibase changelogSync 로 현재 상태를 기준점으로 등록

0개의 댓글