데이터베이스 마이그레이션
데이터베이스 마이그레이션
- 데이터 마이그레이션
- 관계형 데이터베이스 스키마(설계도, 파일)에 대한 증분, 변경 등등
- 스키마를 바탕으로 DB에 데이터를 만들어준다
- 마이그레이션 관리의 필요성
- 작업자간 동일한 데이터베이스 환경을 구성하기 어려움
- DB 스키마 문제가 발생시 해결이 어려움
- Entity 객체의 변화에 DB 스키마가 바로 변경되기 때문에, 데이터 손실이 발생 할 수 있음
Spring boot 고수준 마이그레이션 flyway
– 데이터베이스 스키마의 변경이력을 관리하는 기능을 제공하는 라이브러리. 7가지 기능을 제공함 ddl-auto 대신 사용 가능 Migrate, Clean, Info, Validate, Undo, Baseline 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); } } } } } }
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/
블로그 구독하기 !!