flyway를 왜 도입했는가
- 우리팀은 create문으로 테이블을 따로 생성해두고 ddl-auto를 validate로 적용해 개발했는데,
지난번 프로젝트에 스키마변경이 잦아
변경사항 적용에 시간을 소비하게 되고 조금 불편했다 -
이번 프로젝트에는 배포도 대비할겸 내가 직접 수정하지 않아도 되도록
데이터베이스 형상관리를 해주는 flyway를 도입해보았다! - 이번 프로젝트에서도 스키마의 변경은 잦을 수 밖에 없을텐데,
변경사항을 매번 일일이 찾아 작업하지 않아도 되어 효율적이고
실수 유발 상황을 줄일 것이라 생각된다
=> 결론 : Flyway를 사용하면 직접 DB에 접속해서 SQL을 수정할 필요가 없으니 휴먼에러를 줄일 수 있고, SQL 버전관리 또한 가능해 개발 생산성을 높일 수 있을 것이라 판단하여 도입했다
Flyway
오픈소스 데이터베이스 마이그레이션 툴
= 데이터베이스 형상관리 목적
- 데이터베이스 변경사항 관리를 위한 자바진영 툴
- 데이터베이스의 DDL 이력을 쌓아둠
데이터베이스 형상관리를 왜 해야할까?
- 프로젝트를 진행하다 보면, 데이터베이스가 위 그림처럼 여러 환경에서 존재
- 각자의 로컬 환경에서 개발을 하게 되면, 엔티티의 구조가 변경되고 이로 인해 데이터베이스의 스키마도 변경될 것
-
일일이 스키마 수정을 위한 DDL을 각 환경별로 모두 실행해줘야함
- flyway로 형상관리를 하면?
-> 서버로 배포할 때 자동화 빌드 과정에서 함께 통합되어 DDL이 실행됨- 참고) 위의 그림 설명 : Axel과 Christian이 별개로 DDL을 만들었더라도 통합되어 실행되게 된다
flyway_schema_history 테이블
flyway에서 형상관리를 위하여 자동으로 만드는 테이블
- Flyway는 아무것도 없을 때 metadata table이라는 것을 만듬
= 변경 내역을 저장하는(변경 이력을 쌓아두는) 테이블
select * from flyway_schema_history
- version
- checksum : 파일의 내용을 hashing한 것
- success : 파일실행이 성공했는지 여부 -> 이 값에 따라 flyway가 파일내용 실행여부 결정함
SpringBoot project에서 flyway로 데이터베이스 형상관리하기
설정하기
- Spring Boot에서 기본적으로 Flyway와 Liquibase라는 고수준의 데이터베이스 마이그레이션 도구를 지원함 참고
- Gradle에 스크립트를 작성하는 등 CLI에서 Flyway를 사용할 필요가 없음 CLI에서 사용하기 참고
- dependency
- Spring Boot 2.7.x을 사용 중이기 때문에 7버전을 사용했다
implementation 'org.flywaydb:flyway-core:7.0.0'
- DBMS가 MySQL 8.X 버전이기 때문에 하나 더 추가해주었다
implementation 'org.flywaydb:flyway-mysql'
- yaml 파일 설정
- Spring Boot는 DataSource 설정으로 Flyway를 자동으로 연결
- Spring Boot에서 flyway에 대해 autoconfigure 지원 -> properties or yml 이용 가능
- prefix : spring.flyway
spring:
datasource:
hikari:
jdbc-url: jdbc:mysql://localhost:3306/(db)
username: (username)
password: (password)
jpa:
hibernate:
ddl-auto: validate
flyway:
enabled: true #default지만 명시해주었음
locations: classpath:/db/migration # migration 파일들이 위치하는 directory
sql-migration-suffixes: sql # 파일 확장자
baseline-on-migrate: true # flyway_schema_history 테이블을 자동으로 생성할지 여부
baseline-version: 1 # 최초 버전 정보, default 1이지만 명시해주었음
마이그레이션 스크립트 작성
flyway에서는 데이터베이스에 일어나는 모든 행위를 마이그레이션(migration) 이라고 표현함
- 마이그레이션은 파일로 관리
- 파일의 이름을 지정하는 형식이 있음
- 마이그레이션 스크립트를 추가할 때에는 항상 최신 마이그레이션 스크립트의 버전보다 큰 숫자로 버전을 설정해야함
- 최신 마이그레이션 버전의 숫자보다 작은 숫자의 버전으로 마이그레이션 스크립트를 추가한다면, 그 마이그레이션 스크립트는 무시됨
- 하나의 파일에 1개의 DDL만 두기
- flyway는 checksum을 파일 단위로 관리하며, 파일에 문제가 생겼을 때 이 이후의 로직을 실행하지 않기 때문
flyway 파일 이름 설정하는 방법
from flyway 공식문서
- 파일 경로 :
resources/db/migration
- 파일명 :
V1__init.sql
- 언더바(_) 2개!
Versioned Migrations
마이그레이션 스크립트의 최신 버전과 현재 데이터베이스의 스키마 버전을 비교하고,
차이점이 있다면 마이그레이션 스크립트를 순차적으로 실행하여 최신 스키마와 격차를 좁혀 나감
- Spring Boot를 실행 후 DbMigrate에서의 로깅 확인
- 만들어둔 버전들에 대한 DDL이 실행되고 있는 것 확인
Undo Migrations
Flyway Teams라는 유료 버전에서만 사용가능
Repeatable Migrations
모든 마이그레이션 스크립트가 실행된 이후 실행되는 스크립트
- Repeatable Migrations끼리는 description 순서대로 실행됨
- 한번 실행됨
- 파일이 변경되어 checksum이 변경되면 또 실행됨
알고있기
- 당연하지만, schema.sql, data.sql을 통해 데이터베이스 스키마 초기화하고, 데이터를 추가하는 기능과 Flyway는 함께 사용해서는 안됨
- Entity 구조가 변경되면 꼭 마이그레이션 스크립트 작성하기
- 일반적으로 프로덕션에서는 ddl-auto를 validate로 설정
- schema에 대한 모든 변경은 반드시 새로운 버전의 마이그레이션 스크립트를 추가하는 방법으로 진행하기
- Flyway는 각 마이그레이션 스크립트별로 checksum을 비교하여 유효성을 검사하기 때문에 수정이 아닌 새로 만들어 변경을 반영하기
Reference
Flyway Documentation
Flyway Documentation - why
Flyway로 Java에서 DB schema, seed 관리하기
flyway를 통해 DDL 형상관리를 하자
데이터베이스 마이그레이션을 위한 Flyway 적용기