DB 마이그레이션 Tool:
。DB Schema의변경 이력을 추적하면서코드로 관리하고,버전별로 구분하여 자동 적용하는도구
▶ 수작업으로SQL 작업을 수행하는게 아닌,버전 관리가능한코드로 관리
。Git과 비슷한형상관리역할을 수행하며,UNDO를 수행할 수 있음.
。JAVA기반의마이그레이션 Tool:flyway,Liquibase
。Liquibase:YAML 기반 설정및NOSQL - RDBMS간호환성이 좋음.
。Flyway:SQL 기반이라 사용은 간편하지만,호환성은 나쁨.
Flyway
。DB Schema변경을SQL 파일 버전 기반으로 관리하는DB Migration Tool
▶테이블 생성 / 컬럼 추가 / 인덱스 변경 / 데이터등의 작업을SQL 파일 버전으로 관리하고 자동으로 실행하는 도구
。관리 대상 DB에Migration 파일에 정의된DB Schema로 자동으로 생성
▶ 수동으로DB 구조 변경을 수행할 필요가 없음.
。DB 변경 이력을Migration 파일(.sql)로 버전별로 관리하여DB Schema의형상 관리및변경 이력을 추적이 가능
。DB 버전 별로Roll back을 수행하는 경우flyway cli를 통해UNDO를 수행
。JPA Buddy를 활용하여Entity Class를 기반으로Migration 파일을 생성 가능
데이터베이스생성
。Flyway가형상관리를 수행할Flyway 관리 대상의DB를 생성DROP DATABASE 데이터베이스명; CREATE DATABASE 데이터베이스명 ;
Flyway 의존성설정
。Spring에서 기본적으로Flyway에 대한Starter를 제공
。starter 설정후프로젝트 생성시src/main/resources/db/migration 디렉토리가 자동 생성
▶Flyway는 해당디렉토리에서Migration 파일을 저장 및 관리
application.yml을 통해Auto-Configuration설정
。AutoConfiguration을 통해 해당설정의객체가Spring Bean으로 등록spring: datasource: url: jdbc:mysql://localhost:3306/데이터베이스명 username: 유저명 driver-class-name: com.mysql.cj.jdbc.Driver password: 비밀번호명 jpa: hibernate: ddl-auto: none flyway: enabled: true locations: classpath:db/migration baseline-on-migrate: false validate-on-migrate: true
JPA사용 시hibernate의ddl-auto: none또는validate설정
。일반적으로운영 환경에서만 설정하지만,Flyway에 의해DB Schema 생성을 주도하기위해hibernate에 의한DB Table생성 차단
flyway: enabled기본 : true
。flyway가 적용되도록 설정
▶ 설정 후어플리케이션 구동시관리대상 DB에서flyway_schema_history 테이블이 생성
flyway: locations기본 : classpath:db/migration
。flyway가 참조할Migration 파일의디렉토리 경로를 설정
▶ 기본적으로src/main/resources내db/migration으로 설정
flyway: baseline-on-migrate기본 : false
。이미테이블을 포함하는DB를Flyway 관리 대상으로편입시 사용하는옵션
▶ 현재DB 상태를Baseline Version( 기준선 버전 )으로 등록하고 그 이전migration을 적용하지 않도록 설정
。주로DB내flyway_schema_history 테이블이 없는DB에Flyway를 처음 도입할 때true로 설정
。true로 설정하면Flyway가flyway_schema_history 테이블이 없는 기존DB에 대해 자동으로baseline 작업수행
▶ 이미 존재하는테이블들을기준으로 설정
。flyway는 기본적으로어플리케이션구동 시DB를 비어있는 구조로 간주하여 만약false 상태인 상태에서Migration 파일을 실행 시 중복되는 기존테이블이 존재하는 경우충돌 발생
▶기존 테이블이 이미 존재하는DB에초기 Migration 파일(V1__init.sql)을 실행하면table already exists 오류가 발생하므로true 상태로 설정하여 해당Migration 파일을 적용하지 않도록 설정
。이미Migration 파일이 존재하는DB를Flyway 관리 대상으로 등록 시flyway:baseline-version:을 추가로 선언
▶ 해당버전의Migration 파일부터 실행하도록 설정하여 이전Migration 파일의 실행을 차단하여 충돌 방지
flyway:baseline-version:
。baseline-on-migrate: true를 통해DB를Flyway 관리대상으로 등록 시Migration 파일의실행을 시작할버전을 명시적으로 지정
▶baseline-version: 4인 경우V5__마이그레이션파일.sql부터 실행
baseline-on-migrate원리
。기존DB에users,orders,products의테이블이 존재하는 경우
DB를 처음Flyway 관리 대상으로 등록하는 경우
。간단하게baseline-on-migrate: true로 설정하여 해당DB Table Scheme를Baseline으로서 설정
▶false로 설정하는 경우, 이미DB Table이 존재하는 상태에서 어플리케이션 구동 시 해당DB table의 내용을 정의한초기 Migration 파일실행함으로써충돌발생flyway: enabled: true baseline-on-migrate: true validate-on-migrate: true
- 이미
Migration 파일이 존재하는DB를Flyway 관리 대상으로 등록하는 경우V1__create_users.sql V2__create_orders.sql V3__create_products.sql▶
V3 버전까지의Migration 파일이 존재하는 경우flyway: enabled: true baseline-on-migrate: true baseline-version: 3 validate-on-migrate: true。
baseline-version: 3으로 현재DB 버전을 명시적으로 지정
▶ 어플리케이션 구동 시 해당V3이전마이그레이션 파일은 실행되지않고,V4이후마이그레이션 파일만 실행됨
flyway: validate-on-migrate기본 : true
。Flyway가Migration을 실행 전 기존에 적용된Migration 파일(.sql)이 변경되었는지검증 여부를 설정하는옵션
▶flyway_schema_history 테이블내checksum 값과 현재Migration 파일을 비교하여검증
。동일 버전의Migration 파일이 변경된 경우, 자동으로검증 실패를 발생시켜 이미운영 환경에서 반영 중인Migration 파일이 수정되는 문제를 차단.
▶검증 실패시FlywayValidateException 발생후Migration중단
。운영 환경에서는 일반적으로true로 설정하여Migration 파일의변경 여부를감지하면서무결성을 보장하도록 설정
flyway_schema_history
。DB 마이그레이션 실행 이력을 관리하기 위해 사용하는메타데이터 테이블
▶Flyway가 현재까지 어떤Migration 파일을 실행했는지기록하면서관리
。현재DB가 어떤버전의Migration 파일까지 반영되었고, 어떤Migration 파일을 적용하지 않았는지 판단 시 활용
▶어플리케이션 실행시flyway_schema_history를 통해 반영하지 않은Migration 파일을 식별하여 적용
。checksum을 통해Migration 파일의 무결성을 검증
▶ 이미DB에 실행된Version의마이그레이션 파일을 수정하면checksum 오류가 발생하므로 수정하면 안된다.
。특정Migration 파일에 해당하는데이터 행을 삭제 후 재실행 시 해당Migration 파일을 실행하게됨.
▶flyway_schema_history 테이블자체를 삭제 시 처음부터 실행
▶flyway: enabled: true를 통해DB를Flyway 관리 대상으로 초기 등록 시 생성
DB 내부 구조
installed_rank:Migration 파일실행 순서
version:Migration 버전
▶ 지금까지 실행한Migration 파일의버전을 기록
description:Migration 설명
type:SQL/JDBC여부
script: 실행된Migration 파일명
checksum:파일 checksum
▶검사합: checksum을 기반으로Migration 파일의 수정여부를 검증
installed_by:실행 사용자
installed_on:실행 시간
execution_time:실행 시간(ms)
success:성공 여부
Migration 파일
。DB Schema 변경 이력을버전단위로 관리하기 위한SQL 파일
▶DB 구조 변경을 기록
。spring: flyway: locations로 등록된디렉토리내migration 파일을 생성 및 관리
▶ 기본 :src/main/resources/db/migration
。flyway_schema_history 테이블에 등록된Mgration 파일 실행 기록을 기준으로Flyway는 다음에 실행할Migration 파일을 식별 후 실행
▶flyway_schema_history 테이블삭제 후 실행 시이전 실행 기록이 없으므로, 처음부터db/migration내V1 -> ....순서로Migration 파일을 자동 실행
ex)V1__create_boards.sqlcreate table `boards`( id bigint not null primary key auto_increment, name varchar(255) )
Migration 파일명 컨벤션
。해당파일명 컨벤션을 준수하지 않으면,Flyway에 의해 식별되지 않는다.
{Prefix}{Version}__{Description}.sql
ex )V1__create_user_table.sql
Prefix:
V( Versioned Migration )
。범용적으로 사용되며마이그레이션 파일 버전을 의미하는접두사
▶DB Schema를버전 순서대로 변경 시 사용
。V로 지정된마이그레이션 파일은 한번 실행되면 재실행되지않고,버전 번호기준으로 실행
▶ 이미DB에 실행된Version의마이그레이션 파일을 수정하면checksum 오류가 발생하므로 수정하면 안된다.
R( Repeatable Migration )
。해당 파일에변경사항이 존재하는 경우에 어플리케이션 구동 시마이그레이션을 실행하기위한파일임을 표시하는접두사
ex )R__create_view.sql
。VIEW생성 시 주로 활용하여 수정내용을 기반으로마이그레이션실행
。버전 번호를 기재하지 않고,파일 내용변경 시 재실행
▶flyway_schema_history의checksum 비교를 통해재실행여부 판단
U( Undo Migration )
。특정Versioned Migration을 수동으로UNDO하기 위한파일임을 표시하는접두사
▶V Migration의Rollback 용도로서 활용V2__add_email_column.sql // email 컬럼 추가 U2__remove_email_column.sql // email 컬럼 삭제。일반적으로 활용되지는 않는다.
Version:
。해당Migration 파일의버전을 지시하며,접두사 뒤(V,U)에숫자,_,.를 사용하여버전을 표기
。Flyway는어플리케이션 구동시 해당버전 순서대로 자동으로 실행
ex )V1.1 -> V1.2 -> ...,V1_1_1 -> V1_1_2 -> ....
。application.yml에flyway:baseline-version: 버전설정 시 해당버전의마이그레이션 파일은 전부 적용됨을 간주하여다음 버전의Migration 파일부터 차례대로 실행.
Description:
。해당Migration 파일을설명하는 부분
▶Commit Message같은 느낌.
JPA Buddy를 활용하여Entity를 기반으로Flyway Migration 파일생성
Flyway 의존성정의 및DB생성
create database demo-flyway;
▶Flyway에 의해 관리될DB생성
application.yml에서Flyway관련 설정 수행spring: datasource: url: jdbc:mysql://localhost:3304/demo-flyway username: root driver-class-name: com.mysql.cj.jdbc.Driver password: wjd747 jpa: hibernate: ddl-auto: none flyway: enabled: true locations: classpath:db/migration baseline-on-migrate: false validate-on-migrate: true。초기 설정이므로,
baseline-on-migrate: false를 설정
▶DB를flyway 관리대상으로편입시에만true로 설정
。ddl-auto: none을 설정하여hibernate의DDL에 의해DB Schema가 생성되지 않도록 설정
▶flyway의Migration 파일의해DB Schema가 생성되므로.
- 초기
Application 구동
▶Migration 파일을 정의하지 않았으므로, 식별되지 않았으며DB에 자동으로flyway_schema_history 테이블이 생성되며Flyway 관리대상으로 등록
DB Entity생성 및 해당Entity 설정을 기반으로JPA Buddy를 활용하여Migration 파일생성@Entity public class Post { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; // private String title; }
。Intellij의좌측 ... -> Persistence를 선택
。Persistence에서 생성된Entity 클래스 우클릭 -> New -> Flyway Migration으로 접근
。경로를src/main/resources/db/migration으로 설정 및파일명설정
▶파일명은컨벤션을 지켜서 생성
。DB Entity 설정기반의DDL을 포함하는Migration 파일생성
。어플리케이션구동 시 해당버전 Migration 파일을 식별 후파일내DDL을 실행하여테이블생성
▶V1__create_post_table.sql이므로Flyway에 의해버전1로 등록되어 실행
。flyway_schema_history 테이블에서Migration 파일의실행기록이 보관
▶Flyway는 해당테이블을 참조하여어플리케이션 실행시V1까지의Migration 파일을 실행하지 않고,V2부터의Migration 파일을 실행
Entity 클래스수정 후Migration 파일생성@Entity public class Post { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; // private String title; // private String content; }▶
content 필드추가
。flyway_schema_history 테이블에 등록된 기록에 의해 이전V1__create_post_table.sql은 실행되지 않고, 기록에 없는V2__add_content_column.sql이flyway에 의해 실행됨
▶ 실행 이후flyway_schema_history 테이블에 등록되어 이후재실행시V3 Migration 파일부터 실행
。flyway_schema_history 테이블은DB Table Schema의 변경을마이그레이션 파일버전별로 추적하면서버전관리를 수행