데이터베이스 마이그레이션


데이터베이스 마이그레이션

  1. 데이터 마이그레이션 
    • 관계형 데이터베이스 스키마(설계도, 파일)에 대한 증분, 변경 등등 
    • 스키마를 바탕으로 DB에 데이터를 만들어준다 
  2. 마이그레이션 관리의 필요성
    • 작업자간 동일한 데이터베이스 환경을 구성하기 어려움
    • DB 스키마 문제가 발생시 해결이 어려움 
    • Entity 객체의 변화에 DB 스키마가 바로 변경되기 때문에, 데이터 손실이 발생 할 수 있음 

Spring boot 고수준 마이그레이션 flyway

flyway

 – 데이터베이스 스키마의 변경이력을 관리하는 기능을 제공하는 라이브러리. 7가지 기능을 제공함 ddl-auto 대신 사용 가능   MigrateCleanInfoValidateUndoBaseline and Repair, convention over configuration

  • convention over configuration – 개발자가 Configuration을 하다기 보다 Framework가 Configuration 관습적인 코딩을 이용하자 

Migrate

  • 스키마를 최신 버전으로 마이그레이션 – 스키마 기록 테이블을 자동으로 생성해줌 
  • flyway에게 스키마 파일 위치를 알려줘야함 
  • 디렉토리에 있는 스키마와 DB 스키마가 다를경우 마이그레이션(테이블을 새로 만들어 준다.)
  • Migrate는 데이터와 코드의 기대치(코드상으로 스키마 파일을 구현한것) 사이의 비 호환성을 피하기 위해 애플리케이션 시작 시 실행하는 것을 권장 

Clean

  • 구성된 스키마의 모든 개체를 삭제 
  • 개발 및 테스트에 도옴 
  • 테이블, 뷰, 프로시져 다지움 

info

  • 모든 마이그레이션 대한 세부 정보 

Valid

  • 로컬과 데이터베이스간의 비교

Undo (유료)

  • 마이그레이션 되돌리는 기능 

Baseline

  • 기존에 있던 데이터 베이스를 놔두고 신규데이터 베이스부터 Flyway를 적용하고 싶을때 
  • Flyway 명령어는 신규 데이터 베이스 부터 적용된다. 

Repair 

  • 스키마 기록 테이블 복구

Flyway 사용

SQL

Naming (SQL)

  • versioned Migrations v(prefix)2(version)__add_new_table(설명).sql
  • Undo Migration u(prefix)2(version)__add_new_table.sql
  • Repeated Migration 

스키마 위치 

  • locations 프로퍼티에 명시된 하나 이상의 디렉토리에서 sql 기반 마이그레이션을 검색
  • classpath:db/migration —> resources/db/migration 에서 위 Naming 에 맞는 스키마(.sql) 를 Flyway가 인지 
  • filesystem:/my-project/ —> class path 와 관계없어 file System으로

스키마 코드 (SQL)

CREATE TABLE books(
    id BIGINT NOT NULL,
    name VARCHAR(64),
    author VARCHAR(64)
);

 

 

JAVA

Naming (JAVA)

  • JavaMigration 을 상속하여 SQL의 이름규칙으로 Class를 만든다. 

스키마 위치 

  • classpath:db/migration —> java/db/migration
  • 지정된 패키지 하위의 마이그레이션도 전부 선택이 됨 
  • https://flywaydb.org/documentation/tutorials/java.html

Java 스키마 코드 예시 

package db.migration;

import java.sql.ResultSet;
import java.sql.Statement;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;

public class V3__bulk_update_books extends BaseJavaMigration{
    @Override
    public void migrate(Context context) throws Exception {
        // Statement SQL Query 를 실행하는 인터페이스 
        // context.getConnection().createStatement() 구현체를 리턴 
        try (Statement select = context.getConnection().createStatement()) {
            try (ResultSet rows = select.executeQuery("SELECT id FROM books ORDER BY id")) {
                while (rows.next()) {
                    int id = rows.getInt(1);
                    
                    String nameToChange = "Tonny";

                    try (Statement update = context.getConnection().createStatement()) {
                        update.execute("UPDATE books SET author='" + nameToChange + "' WHERE id=" + id);
                    }
                }
            }
        }
    }
    
}

 

Java Schema location(calsspath:db/migration)

Setting (Gradle)

plugins {
    id "org.flywaydb.flyway" version "7.9.1"
}

flyway {
    url = '[[application.properties 상의 DB URL]]'
    user = 'myUsr'
    password = 'mySecretPwd'
    locations = ['classpath:db/migration']
}


from : https://flywaydb.org/documentation/usage/gradle/

세팅 후 gradle build 를 한번 해줘야 하는 듯 하다. 

  • locations = [‘filesystem:src/org…/resources/db/migration’] 
  • Multiful Database 세팅시에는 Task 옆에있는 문자를 입력해야 Migration 된다. 다른 명령어는 동작 안하는 것 같은데 아마 명령어 별로 세팅을 해줘야 하는건지… 

Command(Gradle)

gradle flywayValidate : 소스상의 스키마가 있는지 보고 있다면 DB 상의 스키마와 비교해 다르면 에러를 출력한다. 실행하게 되면 Schema가 없어도 flyway_schema_history Table 을 데이터 베이스에 생성한다. 

gradle flywayMigrate: 위 명령어로 에러가 발생했다면 해당 명령어로 소스파일 상에 있는 스키마를 DB로 옮겨 테이블을 만들 수있다. 

gradle flywayRepair: 테이블 생성 실패시 해당 명령어를 돌리고 다시 Migrate를 시도 한다. Repair 이전에 서버를 재실행 한다. 

주의 

  • 소스에서 스키마 변경시 Build를 해야 Flyway가 감지한다.  

정리

  • flyway는 마이그레이션을 도와주는 툴 
  • Java 및 SQL 로 schema를 만들어 마이그레이션 가능 
  • SQL 의 경우 Gradle로 Migration 가능, JAVA의 경우 서버 실행 시 Migration 가능 
  • 히스토리 기능을 제공 

참고

fastCampus 스프링 아카데미아 

https://flywaydb.org/



블로그 구독하기 !!

You may also like...