Flyway를 사용하여 Java Spring 프로젝트에서 데이터베이스 형상관리를 적용하는 방법을 다룹니다. 데이터베이스 스키마 변경 이력을 관리하여, 여러 환경에서 데이터베이스의 일관성을 유지하는 것이 목표입니다.
지난글에 로컬 DB를 사용해보았는데요.
2024.08.11 - [JAVA 맨땅에서 CICD 자동화까지] - Docker를 활용한 PostgreSQL 연동 및 로컬 개발 환경 설정
Docker를 활용한 PostgreSQL 연동 및 로컬 개발 환경 설정
이직한 곳에서 Java Spring 프로젝트를 처음 경험하면서 새로운 개발 환경에 필요한 것들을 나와 회사에 추가하면서 같이 성장을 하고자 글을 시작합니다. 이미 다양한 부분을 적용을 했지만 이번
migo-dev.tistory.com
회사에서 DB에 대한 형상관리를 하지 않아 DDL의 변경이력이나 초기 init 이후에도 필수로 필요한 data가 각자 관리가 되었습니다. github에 전체 DDL을 올려두고 관리를 일단 시작했으나, 결국 개발자가 해당 DDL을 각 환경별로 수행해야하는 문제는 해결해야 했고 JPA도입전에 임시적으로 Flyway를 로컬에서 테스트 해보고 팀에 공유하기 위한 적용기입니다.
1. Flyway의 원리와 사용 이유
Flyway의 원리
Flyway는 데이터베이스 마이그레이션을 관리하는 도구로, 데이터베이스 스키마의 버전 관리를 자동화해줍니다. Flyway는 SQL 스크립트를 기반으로 데이터베이스 구조를 변경하며, 각 스크립트는 특정 버전 번호와 함께 관리됩니다. Flyway는 flyway_schema_history라는 테이블을 생성하여, 어떤 마이그레이션이 적용되었는지를 추적합니다.
Flyway의 사용 이유
- 데이터베이스 일관성 유지: Flyway를 사용하면 개발, 테스트, 프로덕션 환경 간에 일관된 데이터베이스 상태를 유지할 수 있습니다.
- 자동화된 마이그레이션: CI/CD 파이프라인에 쉽게 통합하여, 코드와 함께 데이터베이스도 함께 배포할 수 있습니다.
- 롤백 지원: 문제가 발생했을 때, 특정 버전으로 쉽게 롤백할 수 있습니다.
Flyway 설정
Gradle에 Flyway 플러그인 추가
- build.gradle 파일에 Flyway 플러그인을 추가합니다.
plugins {
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'org.flywaydb.flyway' version '8.5.0' // Flyway 플러그인 추가
}
의존성 및 flyway 추가
- dependencies 섹션에 Flyway 의존성을 추가합니다.
dependencies {
implementation 'org.flywaydb:flyway-core' // 추가 설정
runtimeOnly 'org.postgresql:postgresql'
}
// 추가 설정
flyway {
url = 'jdbc:postgresql://localhost:54321/rpa_portal_db'
user = 'test_user'
password = 'test_password'
schemas = ['test_schema']
baselineOnMigrate = true
baselineVersion = '1' // 기존 데이터베이스의 버전을 1로 설정
locations = ['classpath:db/migration']
}
2. 데이터베이스 베이스라인 설정
V1__Baseline.sql 생성
- Flyway가 기존 데이터베이스 스키마를 인식하도록, src/main/resources/db/migration 경로에 V1__Baseline.sql 파일을 생성합니다.
CREATE TABLE person (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INT
);
Flyway 설정
- application-local.yml 파일에 Flyway 설정을 추가합니다.
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1
locations: classpath:db/migration
3. 마이그레이션 실행
Flyway 마이그레이션 실행
- 터미널에서 Flyway 마이그레이션을 실행하여 데이터베이스 스키마를 관리합니다.
./gradlew flywayMigrate -Dspring.profiles.active=local
새로운 마이그레이션 파일 생성
- 추가적인 변경이 필요하다면, 새로운 마이그레이션 파일을 생성하여 Flyway를 통해 관리합니다.
-- V2__Add_email_to_person.sql
ALTER TABLE person ADD COLUMN email VARCHAR(255);
4. Flyway 유용한 명령어 10가지
Flyway를 사용할 때 알아두면 좋은 명령어를 예제와 함께 소개합니다.
1. 마이그레이션 실행
./gradlew flywayMigrate -Dspring.profiles.active=local
- 모든 마이그레이션 파일을 실행하여 데이터베이스를 최신 상태로 만듭니다.
2. 마이그레이션 정보 확인
./gradlew flywayInfo -Dspring.profiles.active=local
- 데이터베이스에 적용된 마이그레이션 정보를 확인할 수 있습니다.
3. 마이그레이션 체크섬 검증
./gradlew flywayValidate -Dspring.profiles.active=local
- 모든 마이그레이션 파일의 체크섬을 검증하여, 변경 여부를 확인합니다.
4. 마이그레이션 수동 수리
./gradlew flywayRepair -Dspring.profiles.active=local
- 오류가 발생한 마이그레이션을 수리하고, flyway_schema_history 테이블을 정리합니다.
5. 마이그레이션 롤백
Flyway는 기본적으로 롤백 기능을 제공하지 않으나, 수동으로 롤백 스크립트를 작성하여 특정 버전으로 롤백할 수 있습니다.
DELETE FROM flyway_schema_history WHERE version = '2';
6. 마이그레이션 초기화
./gradlew flywayBaseline -Dspring.profiles.active=local
7. 마이그레이션 재실행
./gradlew flywayClean -Dspring.profiles.active=local
./gradlew flywayMigrate -Dspring.profiles.active=local
8. SQL 스크립트 적용
./gradlew flywayMigrate -Dflyway.locations=filesystem:src/main/resources/db/scripts
- 특정 SQL 스크립트를 Flyway를 통해 실행할 수 있습니다
9. 환경에 따른 마이그레이션 파일 적용
특정 환경에만 적용할 마이그레이션 파일을 분리할 수 있습니다. 예를 들어, qa 환경 전용 마이그레이션(yml)
flyway:
locations:
- classpath:db/migration
- classpath:db/qa
10. 마이그레이션 버전 강제 설정
./gradlew flywayBaseline -Dflyway.baselineVersion=3
- 특정 버전을 강제로 설정할 수 있습니다.
결론
Flyway를 사용하면 데이터베이스 스키마의 변경 이력을 체계적으로 관리할 수 있습니다. 이번에는 Flyway를 설정하고 마이그레이션을 적용하는 방법을 알아보았습니다. 이를 통해 여러 환경에서 일관된 데이터베이스 상태를 유지할 수 있습니다.
이번에는 로컬 환경에서의 데이터베이스 형상관리를 다루었습니다. 앞으로의 포스트에서는 QA, Staging, 그리고 Production 환경까지 확장하여 CI/CD 파이프라인을 구축하고 자동 배포를 설정하는 방법을 다룰 예정입니다.
다음 포스트에서 뵙겠습니다!