개요
수년 전 개발했던 프로젝트 중 mysql 5.x 버전으로 개발된 프로젝트의 Mysql 버전을 8.x 버전으로 올리고, 간단한 마이그레이션이 필요하여 Spring sql init으로 사용하던 DB 스키마 정의를 Flyway를 적용하여 마이그레이션 한다.
Flyway
Database migrations made easy
- Free - API/CLI and Desktop GUI
- Buil on Open Source
- Version control your database migration scripts
- Powered by the Flyway commnity and Redgate
Flyway는 DB 마이그레이션을 지원하는 도구로 API/CLI와 GUI 툴을 제공하며 다양한 데이터베이스를 제공한다.
또한 Spring Boot와 통합되어 애플리케이션의 마이그레이션 도구로 사용할 수 있다.
동작 방식
Spring에서 Flyway에 동작 방식은 마이그레이션 정보를 관리할 flyway_schema_history 테이블을 생성하고, 버전별로 생성된 SQL 파일을 읽어서 마이그레이션 한다.
flyway_schema_history 생성
Spring에서 Datasource를 설정하고 flyway 설정을 추가하면 기본적으로 flyway에서 사용하는 관리용 테이블을(flyway_schema_history) 생성한다.
DB Migraion 실행
관리 테이블이(flyway_schema_history) 생성되면 리소스 디렉터리(src/main/resources) 하위에 db.migraion 디렉토리 하위에 있는 sql 파일 들을 조회하여 버전별로(파일 이름으로 정의) 마이그레이션을 실행한다.
Migraion 정보 저장
위에서 SQL 파일로 마이그레이션을 실행하면 처음에 생성한 관리 테이블에(flyway_schema_history) 마이그레이션을 실행한 결과를 저장한다.
자세한 동작 방식은 공식 문서를 참고한다. (https://documentation.red-gate.com/fd/getting-started-with-flyway-184127223.html)
Spring Boot에서 Flyway 연동
Flyway Dependencies 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-mysql'
runtimeOnly 'com.mysql:mysql-connector-j'
}
Migraion SQL 추가(Ver 1)
리소스 디렉토리(src/main/resources) 하위에 db.migration 디렉터리를 생성하고 SQL 파일을 작성한다.
SQL 파일 형식은 아래와 같다.
V<Version>__<Name>.sql
ex) V1__init_schema.sql (V1 다음 언더바 2개)
# V1__init_table.sql
CREATE TABLE `user` (
`id` SEERIAL PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`created` DATE NOT NULL
)
Spring Datasource를 설정한다.
# application.properties
spring.flyway.enabled=true
spring.datasource.url={jdbc url}
spring.datasource.username={user name}
spring.datasource.password={password}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
애플리케이션 실행
[flyway-test] [ restartedMain] org.flywaydb.core.FlywayExecutor : Database: jdbc:mysql~~ (Mysql 8.0)
[flyway-test] [ restartedMain] o.f.core.internal.command.DbValidate : Successfully validataed 1 migraion (execution time 00:00.041s)
[flyway-test] [ restartedMain] o.f.core.internal.command.DbMigrate : Cuurrent version of schema 'flyway' << Empty Schema >>
[flyway-test] [ restartedMain] o.f.core.internal.command.DbMigrate : Migrating schema 'flyway' to version "1 - init table"
[flyway-test] [ restartedMain] of.core.internal.command. DbMigrate : Successfully applied 1 migraion to schema 'flywway', not at version v1 (execution time 00:00.088s)
SHOW tables;
flyway_schema_history
user
Migraion SQL 추가(Ver 2)
아래 파일을 db.migration 디렉토리에 추가하고 애플리케이셔을 다시 실행한다.
# V2__add_item_table.sql
CREATE TABLE `item` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`created` DATE NOT NULL
)
신규로 추가한 item 테이블까지 생성된 모습을 볼 수 있다.
SHOW TABLES;
flyway_schema_history
user
item
기존 SQL 스크립트 변경하기
이미 스키마가 반영된 SQL 파일을 수정하여 애플리케이션을 재 실행하면 SQL이 변경되었다는 오류를 발생하고 애플리케이션은 실행에 실패한다.
# V2__add_item_table.sql
CREATE TABLE `item` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`created` DATE
)
버전 2로 작성한 item테이블에 created 칼럼에 NOT NULL 조건을 삭제하고 실행하면 아래와 같은 오류가 발생한다.
Migraion checksum mismatch for migraion version 2
-> Applied to database : 1777652537
-> Resolved locally : 191147207
Spring 기본 SQL 스크립트를 사용한 DB 초기화
Spring boot에서도 spring.sql하위의 설정으로 데이터베이스의 스키마를 초기화하거나(schema.sql) 데이터를 입력하는(data.sql) 기능을 지원하지만 Flyway와 같은 마이그레이션 도구를 사용하는 경우 위 설정들에 대하여 사용하는 것을 권장하지는 않는다.
참고
'dev > spring' 카테고리의 다른 글
[Spring Batch] - AbstractPagingItemReader 조심하기 (0) | 2024.08.21 |
---|---|
[Spring Batch] 5.1.2 Features (0) | 2024.08.21 |
Java JVM - Checkpoint Restore (CRaC) (0) | 2024.07.20 |
[Spring] Springdoc-openapi 사용하여 API 문서 만들기 (0) | 2024.07.16 |
Kubernetes에서 Spring @Scheduled 사용하기 (0) | 2024.07.09 |