글을 쓰게 된 이유
'우아한 테크코스'(이하 우테코)에서 운이 좋게 '프롤로그' 운영 및 개발 근로를 맡게 됐습니다.
그래서 온보딩 과제 중 하나인 Flyway를 맡게 되었고, 크루원들에게 설명하고자 해당 글을 작성했습니다.
Flyway란?
DB의 버전 제어를 통해 쉽고 확실하게 DB migration을 도와주는 Tool입니다.
즉, DB의 형성관리 툴로 DB 버전의 Git이라고 생각하시면 됩니다.
스크립트를 통해 DB의 DDL 변경 이력을 쌓아서 DDL이 어떻게 변화되었는지 관리합니다.
굳이 DDL 변경 이력을 관리해야 하나요?
배포가 이미 완료된 복잡하고 많은 data가 있다고 가정해 보겠습니다.
개발 중 새로운 필드를 추가하게 되었다면 어떻게 처리할 수 있을까요?
1. 배포 서버 DB에 직접 들어가서 Table을 수정한다.
2. 여러 table에 변경사항이 생겼다면 변경사항을 table마다 수정해줘야 한다.
3. 여러 대의 서버가 있다면 서버마다 들어가서 Table을 수정해야 한다.
이는 결국 휴먼 에러 발생 확률이 증가하게 됩니다.
Flyway를 사용하게 된다면 어떻게 할 수 있을까요?
스크립트를 작성하고, 배포 이후에는 스크립트에 의해 관리됩니다.
즉, table을 직접 수정하지 않고, 변경 사항을 스크립트를 관리하여 위의 문제를 해결할 수 있습니다.
Script Version
// v1
drop table if exists account;
create table account
(
id bigint auto_increment,
primary key (id)
);
// v2
alter table account add column age integer default 0;
alter table account add column name varchar(255);
// v3
alter table account drop name;
// v4
insert into account
values (1, 3);
insert into account
values (2, 4);
insert into account
values (3, 5);
Spring에서 flyway 설정
dependency
dependencies {
// ...
implementation 'org.flywaydb:flyway-core' // 추가
implementation 'org.flywaydb:flyway-mysql' // 추가
}
flyway를 사용한다면 core를 추가, MySQL을 사용하므로 flyway-mysql 추가해야 합니다.
yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/practice
username: root
password: 1234
jpa:
generate-ddl: false
flyway:
enabled: true
baseline-version: 0
out-of-order: true
baseline-version의 default 값은 1입니다.
intellij로 애플리케이션 실행하게 되면 baseline-version 이 제대로 실행되지 않는 것을 알 수 있습니다. 즉, script version v1부터 순차대로 읽습니다.
아래 gradle build와 비교해 보겠습니다.
gradle build에서의 flyway
// 추가
buildscript {
dependencies {
classpath 'org.flywaydb:flyway-mysql:9.16.3'
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.10'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id "org.flywaydb.flyway" version "9.16.3" // 추가
}
// 추가
flyway {
url = 'jdbc:mysql://localhost:3306/practice'
user = 'root'
password = 1234
baselineVersion = 0
outOfOrder = true
}
baseline 설정
flyway 옵션을 하나씩 살펴보겠습니다.
baselineVersion 은 어느 스크립트부터 읽을 것인지 baseline version
을 지정해줍니다.
만약 0이라면 V1부터, 1이면 V2부터 스크립트를 읽고, default 값은 1입니다.
그래서 지금 flyway script는 V1부터 시작하기 때문에 version을 0으로 설정하겠습니다.
baseline을 설정하는 gradle 명령어
./gradlew flywayBaseline
version 이 0부터 시작하기 때문에 V1 스크립트부터 실행됩니다.
하지만 위에서 말했듯이 intellij로 애플리케이션을 실행하면 Baseline이 따로 만들어지지 않고, V1부터 실행됩니다.
migration
이제 migration을 해보겠습니다.
./gradlew flywayMigrate -i
-i 옵션은 history 가 어떻게 추가됐는지 추가 로그를 보여줍니다.
clean
이제 clean을 해보겠습니다.
script를 통해 생성된 테이블과 history 가 전부 삭제됩니다.
cleanDisabled = false
cleanDisabled default 값은 true이기 때문에 false로 변경해줘야 합니다.
true면 clean 명령어가 동작하지 않습니다.(flyway에서 아예 막아두었습니다)
./gradlew flywayClean
제대로 삭제됨을 알 수 있습니다.
REFERENCES
gradle buildscript dependency 추가
'Infra' 카테고리의 다른 글
[prolog] prolog 에 로그 모니터링 시스템 구축기(2) (2) | 2023.08.02 |
---|---|
[prolog] prolog 에 로그 모니터링 시스템 구축기(1) (0) | 2023.08.02 |
[monitoring] local에서 filebeat + elasticsearch + grafana를 통해 모니터링 시스템 구축해보기 (2) | 2023.07.06 |
[GitHub Actions] GitHub Actions + Docker를 이용하여 CI/CD (0) | 2022.05.22 |