- 배포된 데이터베이스의 스키마를 변경해보자(1)2025년 03월 11일 22시 35분 20초에 업로드 된 글입니다.작성자: do_hyuk
프로젝트 리팩토링을 진행 중에 code post와 member 테이블 간의 연관관계를 끊어야 할 상황이 생겼기 때문에 고민하게된 내용이다.
대부분의 개발자들은 업데이트를 진행하면서 데이터베이스의 구조를 변경할 상황이 무조건적으로 생길 것이라 생각한다.
이때 이미 배포된 데이터베이스의 정보를 수정하고 다시 배포해 버리면 이전 데이터와 새로운 데이터 간의 차이가 발생하고 만다.
이를 해결하기 위해서는 손수 개발 DB와 운영 DB에 DDL, DML 명령어를 사용하여야 한다.
하지만 그럴 경우 개발자의 실수 즉, 휴먼 에러로 인해 두 DB 간의 구조가 불일치할 수 있는 경우가 생길 수 있다.
이러한 상황을 방지하고자 DB 형상 관리 도구인 Flyway를 도입하고자 한다.
Flyway 란?
Flyway는 데이터베이스의 형상 관리를 목적으로 하는 오픈소스 마이그레이션 툴이다.
Flyway를 통해 변경 사항을 추적하고, 업데이트나 롤백을 보다 쉽게 할 수 있다.
우리가 개발하며 필수적으로 사용하는 git에서 코드를 형상 관리하듯 데이터베이스도 형상 관리가 가능한 것이다.
형상 관리를 하면 데이터베이스 schema의 변경 이력이 남기 때문에 데이터베이스의 변경 작업을 안전하게 할 수 있다.
또한 Migration을 자동으로 해주기 때문에 각기 다른 환경 사이에 스키마를 통일시키기 쉬워진다.
Flyway를 선택한 이유
자바 진영 DB 관리 도구에는 크게 Flyway, Liquibase 가 있다는 것을 알았고, 이 중에서 Flyway가 문서화가 더 잘되어있고 관련 자료가 많기 때문에 선택하게 되었다.
현재 Ori 서비스의 환경별 데이터베이스 상황은 아래와 같다.
- local: MySQL, ddl-auto: create
- dev: MySQL, ddl-auto: create
- prod: RDS(MySQL), ddl-auto: update
환경마다 ddl-auto 옵션이 다르기 때문에 엔티티 구조가 변경되었을 때 일부 환경에서 반영이 되지 않아 conflict가 발생할 수 있다.
단순히 개발 단계에서는 ddl-auto: create 옵션처럼 테이블을 다 날리고 새로 생성하는 것이 편하겠으나, 운영 서버에서는 회원들의 데이터가 담겨있기 때문에 해서는 안되는 행동이다.
그렇기 때문에 Flyway를 통해 테이블 변경에 유연하게 데이터베이스를 관리하고자 한다.
Flyway 동작 원리
Flyway가 비어있는 데이터베이스와 연결되었을 때
flyway 는 DB 버전 관리를 위해 flyway_schema_history라는 테이블을 사용한다.
처음에는 flyway_schema_history 테이블을 찾고, 비어있는 데이터베이스이기 때문에 해당 테이블이 없으므로 이를 찾지 않고 대신 생성한다.
이제 우리의 DB는 flyway_schema_history라는 하나의 빈 테이블이 있는 모습이 되었다.
flyway_schema_history 테이블은 데이터베이스의 상태를 추적하는데 사용된다.
flyway는 마이그레이션을 위해 SQL 또는 Java 작성된 파일을 스캔한다.
스크립트 파일은 `/resources/db/migration` 디렉토리에 적어주면 된다.
마이그레이션이란 일련의 변경 단위를 의미한다.
ex) 테이블이 1개 생성되고, 2개 수정되는 것이 한 묶음일 경우 이는 하나의 마이그레이션으로 본다.마이그레이션은 버전 번호를 기준으로 정렬되어 순서대로 적용된다.
숫자가 작은 버전부터 큰 버전 순서대로 실행된다.
! 버전은 정수로 인식되므로 3.10과 3.2 중 3.2가 먼저 실행된다는 것을 주의 !
각 마이그레이션이 적용되면, schema history 테이블에도 마이그레이션 내역이 함께 기록된다.
Flyway에는 Versioned / Undo / Repeatable Migration 3 종류가 있다.
Versioned Migrations
Flyway의 핵심 기능으로, 마이그레이션 스크립트의 최신 버전과 현재 데이터베이스의 스키마 버전을 비교하고, 차이점이 있다면 마이그레이션 스크립트를 순차적으로 실행하여 최신 스키마와 격차를 좁혀 나간다.
마이그레이션 버전이 1부터 9까지 있고, 현재 개발 환경의 데이터베이스 스키마가 5 버전이라면, 최신 버전에 대해 마이그레이션을 실행하면 6~9 버전의 마이그레이션 스크립트가 순차적으로 실행된다.
만약 개발 환경의 데이터베이스 스키마가 9 버전이라면 마이그레이션 스크립트와 차이점이 없으므로 아무 일도 발생하지 않는다.
Undo Migrations
Flyway 의 유료 버전에서만 사용 가능하다.
가장 최근에 적용된 Versioned Migration을 실행 취소한다.
Repeatable Migrations
모든 마이그레이션 스크립트가 실행된 이후 실행되는 스크립트이다.
Repeatable Migrations 끼리는 description 순서대로 실행된다.
한 번 실행되며, 파일이 변경되어 체크섬이 변경되면 또 실행된다.
Flyway의 개념에 대해 알아보았으니 이제 실제로 도입해보겠다.
의존성 추가
# Flyway 라이브러리 사용을 위한 기본적인 의존성 추가 implementation 'org.flywaydb:flyway-core' # MySQL 을 사용해야한다면 추가 implementation 'org.flywaydb:flyway-mysql'
MySQL - Redgate Flyway - Product Documentation
MySQL Page last updated 27 February 2025 Published 15 January 2025 Verified Versions: 5.7, 8.0, 8.1 Maintainer: Redgate Supported Versions and Support Levels Drivers - MySQL MariaDB URL format jdbc:mysql://host:port/database jdbc:mysql://host:port/database
documentation.red-gate.com
JPA 설정
flyway 로 스키마가 제대로 적용되는지 확인해보기 위해 개발서버가 아닌 로컬에서 진행해 볼 것이다.
application-local.yml 에서 ddl-auto 옵션을 create에서 validate로 변경한다.
# local spring: jpa: show_sql: true hibernate: ddl-auto: validate
ddl-auto 옵션을 validate로 설정하면, 데이터베이스 스키마와 JPA Entity 구조가 같은지 비교하고, 다를 경우 어플리케이션을 실행하지 못하도록 한다.
Flyway 활성화
spring: flyway: enabled: true
현재는 로컬 환경에서만 테스트를 진행해 볼 것이기 때문에 application-dev 와 application-prod 에는 false로 설정하겠다.
이 다음은 프로젝트를 이미 진행하고 있어서 테이블 정보가 이미 있는 경우와 그렇지 않은 경우(flyway_schema_history 테이블까지 있거나 모두 없는 경우)로 나뉜다.
spring: flyway: enabled: true baseline-on-migrate: true
이미 프로젝트가 좀 진행된 후에 flyway를 적용하는 경우는 위와 같이 baseline-on-migrate 옵션을 true로 한다.
baseline은 flyway의 기준을 설정해주는 명령어로, flyway_schema_history 테이블이 없는 경우 생성해주는 옵션이다.
default 값은 false 이므로 해당 경우에 포함되어 있지 않으면 생략해도 괜찮다.
그 다음은 V1에 해당하는 마이그레이션 스크립트를 작성해야 한다.
공식 홈페이지 빈 파일이어도 V1에 해당하는 스크립트 파일이 반드시 있어야한다.
모든 마이그레이션이 순차적으로 진행되도록 보장하기 위해, 초기 버전이 존재해야 한다. 나중에 추가되는 버전 역시 이러한 일관성을 유지하기 위해서이다.
스크립트 파일은 /resources/db/migration 에 작성해주면 된다.
Flyway 네이밍 규칙
위에서 이미 말했듯이 Flyway는 버전 번호를 기준으로 정렬 및 적용되기 때문에 스크립트 파일의 이름을 규칙에 맞춰 적어주는 것이 중요하다.
간단하게 V{숫자}__{설명}.sql 이라고 생각하면 된다.
언더바는 2개이다.
결과
로컬 환경 DB에 flyway_schema_history 가 생성이 된 모습 다음 글에서는 로컬 DB 스키마 구조를 변경하고 제대로 적용되는지 확인해 본 뒤 개발 서버에 적용시키겠다.
'포트폴리오 > AutoReview' 카테고리의 다른 글
Flyway_Schema_History 테이블 자동 복구하기 (0) 2025.03.20 배포된 데이터베이스의 스키마를 변경해보자(2) (0) 2025.03.15 연관관계 설정은 필수일까? (0) 2025.03.07 K6로 토큰 인증 절차가 필요한 API 테스트 하기 (0) 2025.02.24 [feature] 댓글 공개 여부 기능 추가(1) (0) 2025.02.21 댓글