목적동작 원리적용 방법최신 버전으로 Migration 자동으로 할 수 있도록 설정Migration, clean 등 조금 더 세밀하게 관리 → plugin, CLI .. ConfigurationsTroubleShooting
목적
- 소스코드를 github로 형상 관리하는 것처럼 DB의 변경사항을 형상관리하는 툴임
- 예를들어 로컬 DB에 어떤 테이블을 만들고 그다음에 그 테이블을 수정한 것을 형상관리(Migration Script 작성)를 해 놓으면
- 다른 DB(local에서 하다가 운영에 배포)에 해당 스키마들을 세팅할 때, Flyway가 알아서 차례대로 Migration Script DDL을 수행하여 똑같은 형태로 table을 생성해줌
동작 원리
- flyway_schema_history 라는 테이블을 만들어서 거기에서 아래와 같이 관리한다고 함. 자세한건 링크 참고

Baseline Migration [ 참고링크 ]
- 여러 마이그레이션이 적용되고 난 후의 데이터베이스의 상태를 하나의 cumulative한 migration으로 나타내기 위해서 사용하는 방식임
적용 방법
최신 버전으로 Migration 자동으로 할 수 있도록 설정
의존성 추가
implementation 'org.flywaydb:flyway-core:8.5.12' implementation 'org.flywaydb:flyway-mysql:8.5.12'
- 위 해당 의존성으로 추가하면 flyway관련 Configuration(flyway db url 설정 등)하지 않고, DataSource 관련 configuration(spring.datasource)만 진행하면 ApplicationContext initialization하면서 mysql url 읽고 알아서 Bean Initialization 진행해줌
- org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class. 여기서 AutoConfiguration 진행됨
classpath 상 db/migration이라는 경로에 migration script를 만들어주어야 함
Flyway failed to initialize: none of the following migration scripts locations could be found:
- classpath:db/migration
만약 이 경로 바꾸고 싶으면 spring.flyway.location 설정으로 변경 가능
Migration script 작성

- prefix - version - description - suffix 순서임
- 예시 :
V1_0_1__add_member.sql
- prefix
- V는 버전 마이그레이션, R은 반복 마이그레이션 용 접두사(반드시 V또는 R로 시작해야함)
반복 마이그레이션은 어떠한 부작용도 없이 반복적으로 실행 가능한 migration을 말함
-- migration.sql -- Create a stored procedure to calculate the total sales for a given product CREATE OR REPLACE PROCEDURE calculate_total_sales(product_id INT) AS BEGIN DECLARE total_sales DECIMAL(10,2); -- Calculate the total sales for the product and store it in the 'total_sales' variable SELECT SUM(sales_amount) INTO total_sales FROM sales WHERE product_id = product_id; -- Display the result DBMS_OUTPUT.PUT_LINE('Total sales for product ' || product_id || ': ' || total_sales); END; /
- version
- 버전 마이그레이션에서만 명시함.
- 숫자와 Dot, underscore 조합으로 구성함
- version과 description사이에는 언더바 2개 반드시 있어야 함
- description
- schema_version 테이블에 저장 시 설명으로 사용
- suffix
- 확장자 기본은 .sql
- Versioned migrations are typically used for: [ Docs 참고 ]
- Creating/altering/dropping tables/indexes/foreign keys/enums/UDTs/…
- Reference data updates
- User data corrections
Flyway가 schema 버전을 관리하는 용도의 flyway_schema_history 테이블을 자동으로 만들어주는 옵션 설정
spring: flyway: baseline-on-migrate:true
Migration, clean 등 조금 더 세밀하게 관리 → plugin, CLI ..
Flyway plugin 설정(Gradle, Maven) & 수동으로 migrate, clean 하는 방법
- plugin 설정
<build> ... <plugin> <groupId>org.flywaydb</groupId> <artifactId>flyway-maven-plugin</artifactId> <version>9.0.1</version> </plugin> ... </build>
plugins { id "org.flywaydb.flyway" version "9.8.1" }
- plugin에서 필요한 Configuration 설정 → flyway.conf 파일 생성
- 환경 변수 방식도 됨
다양한 방식으로 Configuration이 가능함(Flyway Doc 참고)
그 중 flyway.conf 파일 만들어서 관리
flyway.baselineOnMigrate=true flyway.url=jdbc:mysql://localhost:3306/realworld?serverTimezone=UTC&characterEncoding=UTF-8 flyway.user=root flyway.password=1234 flyway.cleanDisabled=false
- plugin 명령어 별로 실행

gradle Flyway plugin
plugins { id "org.flywaydb.flyway" version "8.2.0" } dependencies { implementation 'org.flywaydb:flyway-core:8.5.12' implementation 'org.flywaydb:flyway-mysql:8.5.12' } flyway { url = "jdbc:mysql://localhost:3306/tenwonmoa?serverTimezone=UTC&characterEncoding=UTF-8" user = "root" password = "root1234" }
- 정확한 url을 입력해줬는데도
No database found to handle url
이 에러가 뜬다면 버전을 조정해보기 (8.2.0으로 조정한 것) [ 참고 github 이슈 ]
Configurations
mixed
: whether to allow mixing transactional and non-transactional statements within the same migration. 이걸 가능케 하면 모든 migration들이 transaction 없이 실행될 수가 있음 [ 참고 ]
TroubleShooting
Procedure는 여러 sql 파일에 나누어서 만들어줘야함 ( 이유는 파악 못함.. )
- 아래와 같이 여러개의 PROCEDURE를 하나의 sql 파일에서 관리하면 migration이 실패함
- 하나의 sql에 한개씩만 만들면 문제없이 만들어짐
CREATE PROCEDURE [dbo].[spProcBlockList] @i_type INT, @i_ip VARCHAR(22), @i_reason INT, @o_ret INT OUTPUT AS BEGIN SET NOCOUNT ON; SET @o_ret = 0; IF @i_Type = 0 BEGIN SELECT IP FROM block_list END ELSE IF @i_Type = 1 BEGIN INSERT INTO block_list(ip, reason, create_time) VALUES(@i_ip, @i_reason, GETDATE()); SELECT @i_ip END RETURN; END; CREATE OR ALTER PROCEDURE [dbo].[spGetSceneInfo] @o_ret INT OUTPUT AS BEGIN SET NOCOUNT ON; SET @o_ret = 0; SELECT id, room_type, scene_id, max_user_cnt FROM md_scene_info RETURN; END;
테이블 구조 변경 후 데이터 삽입 쿼리 하나의 version 으로 관리하면 동작을 안함
테이블 구조 변경하는 쿼리와, 데이터 삽입하는 쿼리 각각 버저닝해야함
이유는 추측상 테이블 구조가 변경이 아직 안되었는데 데이터를 삽입하려고 하니 에러발생하는 것같음
- INSERT INTO (col1, col2 ..) values (val1, val2, …), (val1, val2, …) 와 같이 여러 값을 동시에 삽입하는 게 정상동작 안함. 한개씩 INSERT 구문 실행해주어야 함
- Non-transactional query(eg. CREATE INDEX) 를 실행시킬시 계속 hang 걸리는 현상 [ 참고 ]
postgresql에서 인덱스 생성 (CREATE INDEX CONCURRENTLY
)하면서 락걸린 문제..
- 해결책
- postgresql의 Transactional Lock 기능을 끄기 [ Flyway 문서 참고 ]
- This should be set to
false
for statements such asCREATE INDEX CONCURRENTLY
. (default : true ) - 위 문서 참고해서 gradle plugin 이용하여 migrate 성공