flyway로 데이터베이스 스키마 형상관리 하기

ssongkim·2022년 5월 5일
0
post-thumbnail

Overview

flyway는 데이터베이스 스키마를 형상관리 해주는 데이터베이스 마이그레이션 도구입니다.

flyway를 사용함으로써 우리는 git을 이용해 소스코드를 형상관리하며 버전을 관리하고 변동사항을 추적하고 기록하듯이, 데이터베이스 스키마의 변동사항을 확인하고 기록하며 이를 데이터베이스에 마이그레이션해줍니다.

스키마의 변동사항을 확인하고 기록할 수 있다는 것은 무엇을 의미할까요? 코드리뷰가 가능해진다는 미입니다. flyway를 사용함으로써 우리는 스키마 마저 코드리뷰를 할 수 있게 됩니다. 또한 DB 스키마에 문제가 발생했을 때 어느 시점에서 문제가 발생하였는 지 파악을 쉽게 할 수 있어 장애 대응을 빠르게 할 수 있습니다.

spring frameworkJPA를 사용하는 개발환경에서 flyway를 사용해보겠습니다.

시작하기

1. 의존성 설정

maven

<!-- https://mvnrepository.com/artifact/org.flywaydb/flyway-core -->
		<dependency>
			<groupId>org.flywaydb</groupId>
			<artifactId>flyway-core</artifactId>
			<version>{원하는 버전}</version>
		</dependency>

gradle

// https://mvnrepository.com/artifact/org.flywaydb/flyway-core
	implementation group: 'org.flywaydb', name: 'flyway-core', version: '{원하는 버전}'

먼저 flyway-core 의존성을 추가해줍니다.

(!)해당 버전이 우리가 사용하는 데이터베이스를 지원하는 지 꼭 확인하여야 합니다!

2. application.yml 수정

spring:
	...
	datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:test;mode=mysql
    username: sa
    password:

  flyway:
    enabled: true
    baseline-on-migrate: true

  jpa:
    show-sql: true
    generate-ddl: false
    hibernate:
      ddl-auto: validate
  ...

임베디드 H2 데이터베이스를 기준으로한 설정파일 예제입니다.

generate-ddl을 false로 주어 애플리케이션이 동작하며 JPA가 자동으로 동작하며 DDL을 작성하여 DB에 적용하지 못하도록 합니다.
ddl-auto를 validate로 주어 애플리케이션 동작 시 엔티티와 데이터베이스 스키마 간 매핑이 잘 이루어지는지 검증합니다.

3. 스크립트 파일 작성

스프링 애플리케이션 동작 시 기본 설정 경로로 resources/db/migration 하위의 스크립트 파일을 인식해 동작하며 파일 이름 규칙이 존재합니다. 그 규칙은 다음과 같습니다.

스크립트 파일 이름 규칙

V{version}__name.sql

ex) resources/db/migration/V1__init_table.sql

flyway의 마이그레이션 규칙이 존재하는데 마이그레이션은 현재 데이터베이스에 적용된 버전보다 항상 높은 버전의 파일을 인식해 차례대로 적용하게 됩니다.
V10이 이미 데이터베이스에 마이그레이션 되어있는 상태에서 V9파일을 만들면 마이그레이션이 이루어지지 않습니다.

V10이 이미 데이터베이스에 마이그레이션 되어있는 상태에서 V11, V12, V8 스크립트 파일을 작성하였다면 V11, V12만 마이그레이션이 이루어지게 됩니다.

init_table.sql 스크립트 작성

// resources/db/migration/V1__init_table.sql
DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    my_column VARCHAR(100),
); 

version이 1인 스크립트 파일을 작성하였습니다.

스키마 변경을 위한 스크립트 작성

개발을 하다가 컬럼을 추가해야하는 일이 생겼습니다. 다음과 같이 스크립트 파일을 작성하면 됩니다

// resources/db/migration/V2__add_new_column.sql
ALTER TABLE my_table ADD COLUMN hello_new_column INTEGER DEFAULT 0

database vendor에 따라 다른 스크립트 적용하기

JPAORM입니다. mysql을 사용하다가 oracle로 옮겨가고 싶을 때는 어떻게 해야할까요. location을 지정하여 벤더마다 별도의 디렉토리를 만들어 스크립트 파일을 관리하면 됩니다.

location 지정하기

application-prod.yml
flyway:
	...
    locations: classpath:db/migration/{vendor}
    ...

이렇게 location을 지정해주면 h2 사용 시 db/migration/h2 디렉토리를, mysql 사용 시 db/migration/mysql 디렉토리를 찾아 하위에 작성된 스크립트 파일을 읽게 됩니다.

애플리케이션 구동 마다 seed 주기

db seed값을 주어야할 일이 많습니다. 이럴 때 사용하면 고려할만한 것이 Repeatable Migration입니다. 일단 application-local.yml에만 location을 별도로 또 지정해서 local에서만 seed를 줘보겠습니다.

location 지정하기

application-local.yml
flyway:
	...
    locations: classpath:db/migration/{vendor},classpath:db/seed
    ...

Repeatable Migration 스크립트 파일 작성

네이밍 규칙은 다음과 같습니다.

// resources/db/seed/R__01_seed_member.sql
INSERT INTO...;
INSERT INTO...;
INSERT INTO...;
INSERT INTO...;
// resources/db/seed/R__02_....sql
INSERT INTO...;
INSERT INTO...;
INSERT INTO...;
INSERT INTO...;
profile
鈍筆勝聰✍️

0개의 댓글