애플리케이션 개발을 하다보면 데이터베이스 스키마 변경은 매우 빈번하게 일어납니다.
새로운 기능 추가, 성능 최적화, 또는 데이터 모델 개선 등 다양한 이유로 데이터베이스 구조를 수정해야 하는 상황이 발생합니다.
마이그레이션 도구를 사용하지 않았을 경우
우리는 개발, 운영 환경에서 ddl-auto: none 또는 validate 로 옵션을 지정하곤 하는데요.
이는 애플리케이션 실행 시 Hibernate가 자동으로 데이터베이스 스키마를 변경하지 않도록 하기 위함입니다. 이러한 접근 방식은 데이터의 안정성을 보장하지만, 동시에 몇 가지 불편한 점이 있습니다.
- 수동 DDL 실행: 테이블 추가, 컬럼 변경 등이 필요할 때마다 개발자가 직접 해당 환경의 데이터베이스에 접속하여 DDL 문을 실행해야 합니다.
- 버전 관리의 어려움: 데이터베이스 변경 이력을 추적하고 관리하는 것이 복잡해집니다.
- 환경 간 불일치: 개발, 스테이징, 운영 환경 간 데이터베이스 스키마 동기화가 어려워질 수 있습니다.
- 롤백의 복잡성: 문제 발생 시 이전 상태로 돌아가는 것이 쉽지 않습니다.
이러한 문제들을 해결하기 위해 데이터베이스 마이그레이션 도구의 사용이 필요합니다.
이 글에서는 Spring Boot 프로젝트에서 Flyway를 활용하여 데이터베이스 마이그레이션을 효과적으로 관리하는 방법에 대해 상세히 알아보겠습니다. Flyway를 통해 어떻게 데이터베이스 스키마 변경을 버전 관리하고, 여러 환경에서 일관성 있게 적용할 수 있는지, 그리고 개발 워크플로우를 어떻게 개선할 수 있는지 살펴보겠습니다.
Flyway란
Flyway는 데이터베이스 스키마 버전 관리 도구입니다.
SQL 스크립트를 사용하여 데이터베이스 변경사항을 추적하고 적용할 수 있게 해줍니다.
쉽게 말해 앞의 문제점을 해결해주는 도구인데요.
이 flyway를 사용하면 flyway가 스크립트로 작성한 ddl을 알아서 날려주기 때문에 직접 데이터베이스에 접속하여 ddl을 날리지 않아도 됩니다.
이미 데이터베이스가 있다면? Baseline을 알아보자
Flyway의 Baseline은 기존 데이터베이스에 Flyway를 적용할 때 사용하는 중요한 기능입니다.
이미 운영 중인 데이터베이스에 Flyway를 도입할 때 사용합니다. 또한, 특정 시점부터 데이터베이스 변경 이력을 관리하고 싶을 때 유용합니다.
Baseline으로 지정된 버전을 시작점으로 표시합니다. 이 지정된 버전 이전의 모든 마이그레이션은 이미 적용된 것으로 간주합니다. 이후의 마이그레이션만 실제로 적용됩니다.
따라서 현재 데이터베이스 상태를 유지하면서 Flyway 도입이 가능합니다.
본격적으로 도입
flyway 개념에 대해 알아보았으니 이제 spring-boot에 적용하는 것을 토대로 설정을 해봅시다.
Spring Boot 프로젝트에 Flyway 설정하기
1. 의존성 추가
// build.gradle
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-mysql' // MySQL 사용 시
2 application.properties 설정
// properties
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true
spring.flyway.locations=classpath:db/migration
// yml
spring:
flyway:
enabled: true
baseline-on-migrate: true
locations: classpath:db/migration
각 옵션의 의미는 다음과 같습니다.
- spring.flyway.enabled=true
- Spring Boot 애플리케이션에서 Flyway를 활성화합니다.
- 애플리케이션 시작 시 Flyway가 자동으로 마이그레이션을 실행합니다.
- spring.flyway.baseline-on-migrate=true
- 비어있지 않은 데이터베이스에 대해 자동으로 baseline을 설정합니다.
- 기존 데이터베이스에 Flyway를 처음 적용할 때 발생할 수 있는 문제를 예방합니다.
- spring.flyway.locations=classpath:db/migration
- 마이그레이션 스크립트 파일의 위치를 지정합니다.
- 지정된 경로에서 마이그레이션 스크립트를 찾아 실행합니다.
flyway 사용 해보기
이제 설정이 끝났다면 마이그레이션 스크립트를 사용하여 flyway를 사용해봅시다.
먼저 로컬에서 잘 사용이 되는지 테스트를 해볼 것이기 때문에 모든 테이블을 삭제하고 ddl-auto 옵션을 none으로 바꾸어주겠습니다.
삭제하지 않고 기존의 데이터베이스에 이어가고 싶다면 spring.flyway.baseline-on-migrate=true 이 옵션만 신경써서 확인해주세요.
기존 데이터베이스를 자동으로 baseline로 인식합니다.
그 후 기존의 스키마 구조와 동일한 파일을 V1__init.sql 로 작성해줍니다.
그 후 애플리케이션을 실행해주면, flyway_schema_history 테이블과 함께 V1 파일에서 지정했던 ddl 이 실행되어 테이블이 생기게 됩니다. flyway_schema_history을 확인해보면 적용된 마이그레이션 정보를 확인할 수 있습니다.
테이블도 잘 생성이 되었습니다.
여기서 email 컬럼을 추가하는 스키마 변경을 한번 더 해보겠습니다.
// V2__add_member_email.sql
ALTER TABLE member ADD COLUMN email VARCHAR(255);
다시 실행을 해보면?
flyway_schema_history에 버전 2가 성공적으로 작성되었고 member 테이블에도 새로 생성된 email 컬럼을 확인할 수 있습니다.
이렇게 사용까지 해볼 수 있게 되었습니다. 다만 flyway를 사용하면서 주의사항과 팁이 있는데요.
주의사항 및 팁
데이터베이스 특화 문법은 주의
프로젝트 초반부터 사용하지 않아서, 로컬에서 테스트를 해봤는데 다음과 같은 에러가 발생했었습니다.
IF NOT EXISTS와 같은 특정 데이터베이스 특화 문법은 주의해서 사용해야 합니다. 특정 데이터베이스에서만 동작하는 문법을 사용하면 다른 환경에서 마이그레이션이 실패할 수 있습니다.
큰 변경사항은 여러 개의 작은 마이그레이션으로 나누기
큰 변경사항은 여러 개의 작은 마이그레이션으로 나누는 것이 좋은데요. 아래와 같은 이유를 참고하면 좋을 것 같습니다.
- 리스크 관리
- 작은 변경사항은 문제 발생 시 파악과 해결이 쉽습니다.
- 큰 변경사항 중 일부만 실패할 경우, 전체 롤백이 아닌 부분적 수정이 가능합니다. 따라서 문제 발생 시 특정 단계까지만 롤백하기 쉬워집니다.
- 점진적 적용:
- 서비스 중인 시스템에서 대규모 변경을 한 번에 적용하는 것은 위험할 수 있습니다.
- 작은 단위로 나누면 변경사항을 점진적으로 적용하고 검증할 수 있습니다.
- 가독성과 유지보수성:
- 각 마이그레이션 스크립트가 작고 명확할수록 이해하기 쉽고 유지보수하기 좋습니다.
- 변경 이력을 추적하기 쉬워집니다.
- 성능 고려:
- 대규모 변경은 데이터베이스에 큰 부하를 줄 수 있습니다.
- 작은 변경으로 나누면 각 변경의 영향을 최소화하고 필요시 시간대를 나누어 적용할 수 있습니다.
+) spring에서 자동 repair 실행되도록 하기
repair란? 스키마 히스토리 테이블에 문제가 생겼을 때, 이를 해결하기 위한 기능이다.
- 실패한 마이그레이션 항목 제거
- 적용된 마이그레이션의 체크섬, 설명 및 유형을 사용 가능한 마이그레이션의 체크섬과 다시 정렬
- 누락된 모든 마이그레이션을 삭제된 것으로 표시
위와 같은 기능을 해결해주는데, repair는 마이그레이션이 실행될 때에 진행되어야 한다.
Spring의 FlywayMigrationStrategy
스프링에서는 FlywayMigrationStrategy를 제공해주는데,
Flyway 마이그레이션을 초기화하는 데 사용되는 전략으로, 사용자 정의 구현을 @Bean으로 등록하여 기본 마이그레이션 동작을 재정의할 수 있다.
따라서 FlywayMigrationStrategy를 재정의하여, 매 flyway의 migrate 작업이 실행되기 직전 repair를 해준다면 flyway에 문제가 발생해도 적절한 상태에서 migrate 가능하다.
@Configuration
public class FlywayRepairConfiguration {
@Bean
public FlywayMigrationStrategy flywayMigrationStrategy() {
return flyway -> {
flyway.repair();
flyway.migrate();
};
}
}
Flyway를 사용하면 데이터베이스 스키마 변경을 버전 관리하고, 팀 및 환경 간 동기화를 쉽게 할 수 있습니다.
편하게 스키마 관리하세요~~
'우아한테크코스 6기 > 3단계' 카테고리의 다른 글
보내는 사람은 있는데 받는 사람이 없다? 쿠키 내놔 (+CORS) (1) | 2024.08.22 |
---|---|
Loki, Promtail, Grafana를 사용한 로그 모니터링 구축 (0) | 2024.08.13 |
Logback MDC로 쉽게 요청 추적하기 (0) | 2024.08.11 |
NoResourceFoundException 에 대해 알아보자 (0) | 2024.08.11 |
팀 로깅 전략 구상기 (0) | 2024.08.05 |