Flyway 살펴보기
Flyway 살펴보기

Flyway 살펴보기

Tags
Flyway
Database
Published
September 13, 2025
Author
lkdcode

🔥 Flyway?

DB 스키마도 애플리케이션 코드처럼 ‘버전, 히스토리, 리뷰, 배포 파이프라인’ 안에서 관리해야 한다. 다양한 환경에서 데이터베이스의 상태가 불확실하거나 스크립트 적용 여부에 대해 혼란스럽다면, 또 새로운 데이터베이스 설정에 어려움이 있다면 Flyway 를 통해 해결할 수 있다. Flyway를 통해 데이터베이스 형상관리를 어떻게 할 수 있는지 알아보자.
 

🔥 Core concepts

notion image
  • 1: 마이그레이션 파일(스크립트)로 실행할 DDL/DML 을 정의한다. Flyway 는 classpath:db/migration 경로를 스캔해 버전 순서대로 적용할 목록을 만든다.
  • 2: 처음 실행할 때 flyway_schema_history 테이블을 만들고 적용한 각 마이그레이션의 메타데이터(버전, 설명, 체크섬 등)을 한 행씩 기록한다.
  • 3: 히스토리와 파일의 체크섬/버전을 비교해 아직 적용 안 된 스크립트만 실행한다. 이미 기록된 버전은 재실행하지 않고 파일이 바뀌면 validate 단계에서 체크섬 불일치로 실패하게 된다. (필요시 repair)
 
우리가 작성한 스크립트를 기반으로 형상관리가 되는 것이지 테이블의 변경 사항을 직접 추적하지는 않는다. (스크립트에 테이블 변경 사항을 기록하면 추적이 되겠지만) 위의 컨셉을 기억하고 실전으로 가보자.
 

🔥 Flyway 간단 사용

docker-compose 를 참고하여 MySQL 서버를 띄우고 최소한의 의존성으로 flyway 의 동작을 살펴본다.
 

🚀 의존성

상황에 맞게 버전을 선택하면 된다. 본 글에선 11.12.0 버전을 선택했으며 implementation 로 의존성을 추가했는데 컴파일시에 필요가 없거나 테스트에서 사용하지 않을거라면 runtimeOnly 로 추가해도 무방하다.
 

🚀 Yeah! Empty!

비어있는 데이터베이스에 Flyway 를 실행시켜보자 resources/db/migration 에 스크립트는 하나도 없으며 어떻게 동작하는지 아래의 로그로 알 수 있다.
/* 생략.. */ HikariPool-1 - Start completed. Database: jdbc:mysql://localhost:13306/lkdcode-flyway (MySQL 8.0) Schema history table `lkdcode-flyway`.`flyway_schema_history` does not exist yet Successfully validated 0 migrations (execution time 00:00.014s) No migrations found. Are your locations set up correctly? Creating Schema History table `lkdcode-flyway`.`flyway_schema_history` ... Current version of schema `lkdcode-flyway`: << Empty Schema >> Schema `lkdcode-flyway` is up to date. No migration necessary. Tomcat started on port 18080 (http) with context path '/'
익숙한 히카리 풀 로그부터 톰캣 사이에 Flyway 로그가 있는데 살펴보면..
MySQL 에 잘 접속했고 마이그레이션 파일을 0개 찾았다고 한다. 기본 경로인 db/migration 에서 찾지 못했다고 친절하게 알려주고 flyway_schema_history 테이블을 만들었다. 그리고 스키마 버전은 적용된게 없다. 이제 적용할 스크립트가 없으니 종료한다는 로그다.
 
실제 데이터베이스를 확인하면 flyway_schema_history 가 생성되었고 텅 비어있는 것을 확인할 수 있다.
 

🚀 My first migration

이제 DDL 을 작성한 뒤 resources/db/migration 에 올려보자. DDL/DML 은 데이터베이스 제품에 맞게 작성하면 되지만 파일명은 Flyway 의 규칙을 따라야 한다. 파일명에 대한 규칙을 먼저 살펴본다.
 

🚀 V1__my_first_migration.sql

파일명 규칙은 접두사 + version + 구분자 + 내용 + 확장자 형식으로 이루어져 있다.
V1__my_first_migration.sql 는 올바른 규칙을 가진 파일명인데
  • V : 접두사
  • 1 : 버전
  • __ : 구분자
  • my_first_migration : 내용
  • .sql : 확장자
 
파일명의 언더스코어 2개로(spring.flyway.sql-migration-separator 를 통해 설정가능) 접두사+버전과 내용을 구분한다. 접두사에 따라 기능을 달리 수행하게 되므로 접두사에 대해 좀 더 살펴보자!
 

🚀 접두사

접두사로 올 수 있는 값은 총 4개이며 각각 다르게 동작한다.
 

🎯 V - Versioned migration

  • 사용 예시: V1__my_first_migration.sql
 
버전 오름차순으로 딱 한 번 실행된며 실행 결과는 flyway_schema_history 테이블에 기록된다.
테이블/인덱스/제약조건/컬럼 변경 등 순차적 변화를 남기는 모든 작업을 해당 접두사로 수행하면 된다.
 

🎯 R - Repeatable migration

  • 사용 예시: R1__my_first_migration.sql
 
위의 Versioned 가 끝난 뒤 검사한다. 파일의 체크섬이 바뀌면 재실행하게 되는데 반복 가능한 쿼리를 사용하면 된다. 예를 들어 뷰/프로시저/함수/권한처럼 정의(DDL)할 값을 최신으로 유지시키고 싶을 때 사용하면 된다.
(대량의 DML 를 R로 두면 수정 때마다 수행되니 전량 재실행 될 수 있음)
 

🎯 U - Undo migration

  • 사용 예시: U1__my_first_migration.sql
 
V버전을 되돌리는 스크립트이다. flyway undo 등으로 직전 버전부터 역순 적용된다.
 

🎯 B - Baseline migration

  • 사용 예시: B1__my_first_migration.sql
 
Flyway 가 Yeah!Empty! 에서 시작하지 않는다면 해당 접두사를 통해 이미 존재하는 레거시 스키마를 시작점으로 잡을 수 있다. 히스토리가 없을 때 상태를 정의할 수 있고 파일 없이도 baselineOnMigrate=true 등으로 설정할 수 있다.
 
Yeah!Empty! 에서 시작하여 flyway_schema_history 테이블만 생성했으니 다시 작은 시나리오 실전을 통해 어떻게 동작하는지 살펴보자
 

🚀 착실한 버저닝

kiwi 테이블을 추가해보자 DDL 이며 resources/db/migration 에 두면 Flyway 가 잘 읽고 반영한다.
 
notion image
 
  1. Flyway 가 마이그레이션된 스크립트를 읽어 반영하는 로그다. 이때 flyway_schema_history 에 기록하게 되는데 이 중 checksum 컬럼은 파일 바이트 내용을 기반으로 계산한 CRC32 값이다.
  1. 실제 테이블에 값이 추가됨을 확인할 수 있다.
 
이후 tomato, banana 마이그레이션도 잘 추가됨을 확인할 수 있다.
notion image
 
 

🚀 기존 Migration Script 수정하기

Flyway 는 flyway_schema_history 기록된 checksum 을 토대로 migration script 와 비교하게 되는데 새로 버저닝을 하지 않고 수정하면 어떻게 될까?
 
V2__tomato.sql 을 그냥 수정하고 서버를 실행하면 아래와 같이 MySQL 연결 후 바로 셧다운 되는 것을 볼 수 있다.
notion image
 

🚀 DB로 가서 컬럼 삭제하기

Flyway 는 migration script ↔ flyway_schema_history 로만 비교한다니, 테이블로 이동해서 컬럼을 삭제해보자. 기존에 컬럼은 총 6개인데 2개만 남기고 모두 지웠다.
 
Flyway 는 변경사항이 없다고 말하고 있고 서버도 잘 기동됐다. 하지만 실제 데이터베이스에 테이블은 migration script 와 다르게 변경되었다.
notion image
 
Flyway 는 버전 스크립트를 기록하고 순서대로 적용하여 이력을 기록하고 기존 스크립트를 바꾸지 않는다가 원칙이기 때문에 DB 상태의 차이 탐지는 기본 기능이 아니다.
 
Flyway 가 migration script 를 읽어 DDL 을 다시 수행하게 하고 싶다면 flyway_schema_history 로 이동해 해당 레코드를 지워주면 된다. (DDL 을 원한다면 테이블도 지워야한다.)
notion image
 

🚀 Flyway 의 다양한 Properties

spring.flyway.~ 설정들이 다양하므로 상황에 맞게 설정하고 싶다면 아래의 문서에서 확인할 수 있다.
  • Common Application Properties :: Spring Boot