Skip to content

Flyway 이론편

황재현 edited this page Apr 18, 2023 · 1 revision

🐭 Flyway가 무엇이고 왜 필요한가?


Flyway란?

  • DB의 버전 제어를 통해 쉽고 확실하게 DB migration할 수 있게 도와주는 tool
    • DB의 형상관리: git을 통하여 우리가 코드를 관리하는 것의 데이터베이스 버전
    • flyway는 DB의 DDL의 이력을 쌓아서 DDL이 어떻게 변화되었는지 관리하는 툴
      • DDL: data 정의어
        • CREATE: db, table 등을 생성하는 역할
        • ALTER: table 수정하는 역할
        • DROP: db, table 삭제하는 역할
        • TRUNCATE: table 초기화 시키는 역할

왜 필요한가?

  • 배포가 이미 완료된 복잡하고 쌓인 정보가 많은 data를 생각해보자
  • 신기술을 개발하는 도중 새로운 필드를 추가하게 되었다면? 어떻게 변화를 처리할 것인가?
    • 배포 server DB에 직접 들어가서 table을 수정할 수 있지만 매우 힘들다
    • 운영 환경에서는 spring.jpa.hibernate.ddl-auto  옵션을 create 또는 update로 할 수 없다
    • 따라서, 여러 table에 변경사항이 생겼다면 변경사항을 table마다 수정해줘야한다
    • 휴먼 에러 발생 확률 증가
  • flyway는 코드를 관리하는 것처럼 DB 변경 사항을 관리해준다
    • local에서 DB 변경 사항을 추가하는 것으로 배포 이후에는 알아서 관리된다
    • table을 직접 건들지 않고 변경 사항을 파일에 스키마를 작성한다
    • 따라서 위의 문제들이 해결될 수 있다
    • 이를 통해 데이터베이스 스키마 설정 및 유지 관리가 매우 간편해진다
  • Amazon RD, Microsoft SQL, Azure, Google Cloud SQL, Heroku 등 다양한 클라우드와 DB 지원

스크린샷 2023-04-12 오후 4 55 43

  • Plain old SQL: 독점 XML 형식이 없고 일반 SQL script를 사용
  • dependencies 필요 없음: Java 7+와 Jdbc 드라이버만 있으면 된다

Command


Migrate: DB Schema 수정

> gradle flywayMigrate

//sample output
> gradle flywayMigrate -i

Current schema version: 0
Migrating to version 1
Migrating to version 1.1
Migrating to version 1.2
Migrating to version 1.3
Successfully applied 4 migrations (execution time 00:00.091s).

Clean: table, view, procedures 모두 제거

> gradle flywayClean

//sample output
> gradle flywayClean -i

Cleaned database schema 'PUBLIC' (execution time 00:00.016s)

Info: history 출력

> gradle flywayInfo

//sample output
> gradle flywayInfo

Database: jdbc:h2:file:flyway.db (H2 1.3)

+------------+---------+----------------+------+---------------------+---------+----------+
| Category   | Version | Description    | Type | Installed on        | State   | Undoable |
+------------+---------+----------------+------+---------------------+---------+----------+
| Versioned  | 1       | First          | SQL  |                     | Pending | Yes      |
| Versioned  | 1.1     | View           | SQL  |                     | Pending | Yes      |
| Versioned  | 1.2     | Populate table | SQL  |                     | Pending | No       |
+------------+---------+----------------+------+---------------------+---------+----------+

Validate: Schema가 변경됐는 지 검증(해시값으로 비교)

> gradle flywayValidate

//sample output
> gradle flywayValidate -i

Validated 5 migrations (execution time 00:00.030s)

Undo: 가장 최근 적용된 버전 취소

> gradle flywayUndo

//sample output
> gradle flywayMigrate -i

Database: jdbc:h2:file:C:\Programs\flyway-0-SNAPSHOT\flyway.db (H2 1.3)
Current version of schema "PUBLIC": 1
Undoing migration of schema "PUBLIC" to version 1 - First
Successfully undid 1 migration to schema "PUBLIC" (execution time 00:00.024s).

Baseline: 존재하던 DB로 baselineVersion을 만들고 적용

> gradle flywayBaseline

//sample output
> gradle flywayBaseline -i

Creating schema history table: "PUBLIC"."flyway_schema_history"
Schema baselined with version: 1

Repair: 고치는 용도

  • 실패한 마이그레이션 제거
  • 체크섬, 설명 등을 재할당
> gradle flywayRepair

//sample output
> gradle flywayRepair -i

Repair not necessary. No failed migration detected.

🦊 주로 사용하는 명령어, 역할


[options]링크

Migrate

스크린샷 2023-04-13 오후 3 29 50
  • schema를 최신 버전으로 migrate한다
    • 이 때, schema 기록 table이 없는 경우 자동으로 생성
    • flyway workflow의 핵심
    • 사용 가능한 migration을 위해 file system 혹은 class path를 스캔한다
    • DB에 적용된 migration과 비교해 차이가 있으면 DB를 migration하여 차이를 좁힌다

Command Line

> flyway [options] migrate

//sample output
> flyway migrate

//sample json output
> flyway migrate -outputType=json

{
  "initialSchemaVersion": null,
  "targetSchemaVersion": "1",
  "schemaName": "public",
  "migrations": [
    {
      "category": "Versioned",
      "version": "1",
      "description": "first",
      "type": "SQL",
      "filepath": "C:\\flyway\\sql\\V1__first.sql",
      "executionTime": 0
    },
    {
      "category": "Repeatable",
      "version": "",
      "description": "repeatable",
      "type": "SQL",
      "filepath": "C:\\flyway\\sql\\R__repeatable.sql",
      "executionTime": 0
    }
  ],
  "migrationsExecuted": 2,
  "flywayVersion": "9.16.3",
  "database": "testdb",
  "warnings": [],
  "operation": "migrate"
}

Baseline

Untitled

  • 마이그레이션을 적용할 base DDL을 설정할 수 있다. 해당 B{버전} 보다 낮은 버전의 마이그레이션은 모두 무시된다.
flyway [options] baseline

//sample output

> flyway baseline

Flyway 9.16.3 by Redgate

Creating schema history table: "PUBLIC"."flyway_schema_history"
Schema baselined with version: 1

//sample JSON output
> flyway baseline -outputType=json

{
  "successfullyBaselined": true,
  "baselineVersion": "1",
  "flywayVersion": "9.16.3",
  "database": "testdb",
  "warnings": [],
  "operation": "baseline"
}

Clean

스크린샷 2023-04-13 오후 3 04 18
  • 구성된 schema의 모든 개체(table, view, procedure) 삭제
    • 테스트 시 많이 사용
    • production DB에 사용 금지
flyway [options] clean

//sample output
> flyway clean

Flyway 9.16.3 by Redgate

Cleaned database schema 'PUBLIC' (execution time 00:00.014s)

//sample JSON output
> flyway clean -outputType=json

{
  "schemasCleaned": [
    "public"
  ],
  "schemasDropped": [],
  "flywayVersion": "9.16.3",
  "database": "testdb",
  "warnings": [],
  "operation": "clean"
}

Info

스크린샷 2023-04-13 오후 3 22 44
  • 모든 migration들의 상태 정보, 디테일을 출력한다
    • 이를 통해 현재 위치, 적용된 migration, 아직 보류 중인 migration, 실행 시기 및 성공 여부를 한 눈에 확인 가능
flyway [options] info

//sample output
> flyway info -outputType=json

{
  "schemaVersion": null,
  "schemaName": "public",
  "migrations": [
    {
      "category": "Versioned",
      "version": "1",
      "description": "first",
      "type": "SQL",
      "installedOnUTC": "",
      "state": "Pending",
      "undoable": "No",
      "filepath": "C:\\flyway\\sql\\V1__first.sql",
      "installedBy": "",
      "executionTime": 0
    },
    {
      "category": "Repeatable",
      "version": "",
      "description": "repeatable",
      "type": "SQL",
      "installedOnUTC": "",
      "state": "Pending",
      "undoable": "",
      "filepath": "C:\\flyway\\sql\\R__repeatable.sql",
      "installedBy": "",
      "executionTime": 0
    }
  ],
  "allSchemasEmpty": false,
  "flywayVersion": "9.16.3",
  "database": "testdb",
  "warnings": [],
  "operation": "info"
}

Validate

스크린샷 2023-04-13 오후 3 30 49
  • 매번 마이그레이션을 할 때마다 해시값(Checksum)을 저장한다. 이것을 기반으로 변경 사항이 있는 지 검증한다.
  • (DB에 적용된 schema 정보, local의 변경점 비교해서 보여준다)
flyway [options] validate
flyway [options] undo

//sample output
> flyway undo

Flyway 9.16.3 by Redgate

Database: jdbc:h2:file:C:\Programs\flyway-0-SNAPSHOT\flyway.db (H2 1.3)
Current version of schema "PUBLIC": 1
Undoing migration of schema "PUBLIC" to version 1 - First
Successfully undid 1 migration to schema "PUBLIC" (execution time 00:00.024s).

//sample JSON output
> flyway undo -outputType=json

{
  "initialSchemaVersion": "1",
  "targetSchemaVersion": null,
  "schemaName": "public",
  "undoneMigrations": [
    {
      "version": "1",
      "description": "undoFirst",
      "filepath": "C:\\flyway\\sql\\U1__undoFirst.sql",
      "executionTime": 0
    }
  ],
  "migrationsUndone": 1,
  "flywayVersion": "9.16.3",
  "database": "testdb",
  "warnings": [],
  "operation": "undo"
}

Repair

스크린샷 2023-04-13 오후 4 00 05
  • Flyway의 schema history table을 repair한다
    • DDL 트랜잭션이 없는 DB에서 실패한 migration 제거
    • applied migration의 checksum, descriptions, types를 사용가능한 migration들 중 하나와 다시 정렬한다
    • 누락된 모든 migration을 삭제된 것으로 표시
    • 따라서, migration할 때와 동일한 위치에 repair 작업 수행 필요
flyway [options] repair

//sample output
> flyway repair

Flyway 9.16.3 by Redgate

Repair not necessary. No failed migration detected.

//sample JSON output
> flyway repair -outputType=json

{
  "repairActions": [
    "ALIGNED APPLIED MIGRATION CHECKSUMS"
  ],
  "migrationsRemoved": [],
  "migrationsDeleted": [],
  "migrationsAligned": [
    {
      "version": "1",
      "description": "first",
      "filepath": "C:\\flyway\\sql\\V1__first.sql"
    }
  ],
  "flywayVersion": "9.16.3",
  "database": "testdb",
  "warnings": [],
  "operation": "repair"
}
Clone this wiki locally