flyway를 왜 도입했는가

  • 우리팀은 create문으로 테이블을 따로 생성해두고 ddl-auto를 validate로 적용해 개발했는데,
    지난번 프로젝트에 스키마변경이 잦아
    변경사항 적용에 시간을 소비하게 되고 조금 불편했다
  • 이번 프로젝트에는 배포도 대비할겸 내가 직접 수정하지 않아도 되도록
    데이터베이스 형상관리를 해주는 flyway를 도입해보았다!

  • 이번 프로젝트에서도 스키마의 변경은 잦을 수 밖에 없을텐데,
    변경사항을 매번 일일이 찾아 작업하지 않아도 되어 효율적이고
    실수 유발 상황을 줄일 것이라 생각된다


=> 결론 : Flyway를 사용하면 직접 DB에 접속해서 SQL을 수정할 필요가 없으니 휴먼에러를 줄일 수 있고, SQL 버전관리 또한 가능해 개발 생산성을 높일 수 있을 것이라 판단하여 도입했다


Flyway

오픈소스 데이터베이스 마이그레이션 툴
= 데이터베이스 형상관리 목적

  • 데이터베이스 변경사항 관리를 위한 자바진영 툴
  • 데이터베이스의 DDL 이력을 쌓아둠


데이터베이스 형상관리를 왜 해야할까?

ff

  • 프로젝트를 진행하다 보면, 데이터베이스가 위 그림처럼 여러 환경에서 존재
  • 각자의 로컬 환경에서 개발을 하게 되면, 엔티티의 구조가 변경되고 이로 인해 데이터베이스의 스키마도 변경될 것
  • 일일이 스키마 수정을 위한 DDL을 각 환경별로 모두 실행해줘야함

  • flyway로 형상관리를 하면?
    -> 서버로 배포할 때 자동화 빌드 과정에서 함께 통합되어 DDL이 실행됨
    • 참고) 위의 그림 설명 : Axel과 Christian이 별개로 DDL을 만들었더라도 통합되어 실행되게 된다



flyway_schema_history 테이블

flyway에서 형상관리를 위하여 자동으로 만드는 테이블

  • Flyway는 아무것도 없을 때 metadata table이라는 것을 만듬
    = 변경 내역을 저장하는(변경 이력을 쌓아두는) 테이블


select * from flyway_schema_history

flyway_history

  • version
  • checksum : 파일의 내용을 hashing한 것
  • success : 파일실행이 성공했는지 여부 -> 이 값에 따라 flyway가 파일내용 실행여부 결정함



SpringBoot project에서 flyway로 데이터베이스 형상관리하기

설정하기

  • Spring Boot에서 기본적으로 Flyway와 Liquibase라는 고수준의 데이터베이스 마이그레이션 도구를 지원함 참고


  • 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
마이그레이션 스크립트의 최신 버전과 현재 데이터베이스의 스키마 버전을 비교하고,
차이점이 있다면 마이그레이션 스크립트를 순차적으로 실행하여 최신 스키마와 격차를 좁혀 나감


boot_v


  • Spring Boot를 실행 후 DbMigrate에서의 로깅 확인
    • 만들어둔 버전들에 대한 DDL이 실행되고 있는 것 확인

    flayway_console


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 적용기


업데이트: