카테고리 없음

Flyway 사용해보기

필유아사 2023. 4. 25. 14:16

Flyway

Flyway는 오픈 소스 데이터베이스 마이그레이션 도구입니다.

Migrate, Clean, Info, Validate, Undo, Baseline 및 Repair의 7가지 기본 명령을 기반으로 합니다.

마이그레이션은 SQL 또는 Java로 작성될 수 있고, 다양한 데이터베이스를 지원합니다.

 

Why database migrations?

Shiny라는 프로젝트가 있고 Shiny DB라는 데이터베이스에 연결하는 Shiny Soft라는 소프트웨어가 있다고 가정합니다.

대부분의 프로젝트에서는 다음과 같은 과정으로 소프트웨어나 DB를 관리할 것입니다.

개발자의 개발 환경, 단위테스트 환경, 통합테스트 환경, 운영 환경 등으로 구성될 것입니다.

위와 같은 환경에서 software는 버전관리, 형상관리, 배포관리 등이 잘 관리되고 있습니다.

하지만 DB의 변경관리는 상대적으로 잘 관리되고 있지 않습니다.

많은 프로젝트가 수동으로 SQL 스크립트에 의존하여 DB를 관리하고 있습니다.

  • 이 시스템에서 데이터베이스는 어떤 상태입니까?
  • 이 스크립트가 이미 적용되었거나 적용되지 않았습니까?
  • 프로덕션의 빠른 수정이 나중에 테스트에 적용되었습니까?
  • 새 데이터베이스 인스턴스를 어떻게 설정합니까?

 

데이터베이스 마이그레이션 툴(flyway)은 이러한 질문에 대한 대안을 줄 수 있습니다.

  • 처음부터 데이터베이스 다시 만들기
  • 데이터베이스가 어떤 상태인지 항상 명확
  • 현재 버전의 데이터베이스에서 최신 버전으로 마이그레이션

 

How Flyway works

Flyway가 비어있는 데이터베이스와 연결되어 있다고 가정합니다.

flyway는 flyway_schema_history 테이블을 찾으려고 시도하고, 없을 경우 flyway_schema_history 테이블을 생성합니다. 

이 테이블은 데이터베이스의 상태를 추적하는 데 사용됩니다.
그 직후 Flyway는 마이그레이션을 위해 Sql 또는 Java로 작성된 파일(파일 시스템 또는 애플리케이션의 클래스 경로)을 스캔합니다.

마이그레이션은 버전번호를 기준으로 정렬되고 순서대로 적용됩니다.

여기서 마이그레이션이란 표현은 일련의 변경단위로 생각하시면 됩니다. 예를 들면 테이블 2개 생성, 3개 변경 등이 한 묶음인 경우 이를 하나의 마이그레이션으로 보시면 됩니다.

각 마이그레이션이 적용될 때 flyway_schema_history 데이터도 업데이트됩니다.

<flyway_schema_history>

installed_rank version description type script checksum installed_by installed_on execution_time success
1 1 Initial Setup SQL V1__Initial_Setup.sql 1996767037 axel 2016-02-04 22:23:00.0 546 true
2 2 First Changes SQL V2__First_Changes.sql 1279644856 axel 2016-02-06 09:18:00.0 127 true

메타데이터와 초기 상태가 설정되었으므로 이제 최신 버전으로의 마이그레이션을 진행할 수 있습니다.

Flyway는 마이그레이션을 위해 애플리케이션의 파일 시스템 또는 클래스 경로를 다시 한 번 스캔합니다. 마이그레이션은 스flyway_schema_history 의 정보를 기준으로 버전 번호가 현재 버전보다 낮거나 같으면 무시됩니다.

 

보류 마이그레이션은 아직 적용되지 않은 마이그레이션입니다.

마이그레이션은 버전 번호별로 정렬되고 순서대로 실행됩니다.

 

flyway_schema_history 테이블이  업데이트됩니다.

installed_rank version description type script checksum installed_by installed_on execution_time success
1 1 Initial Setup SQL V1__Initial_Setup.sql 1996767037 axel 2016-02-04 22:23:00.0 546 true
2 2 First Changes SQL V2__First_Changes.sql 1279644856 axel 2016-02-06 09:18:00.0 127 true
3 2.1 Refactoring JDBC V2_1__Refactoring   axel 2016-02-10 17:45:05.4 251 true

DDL 또는 DML에 관계없이 데이터베이스를 변경시켜야 할 때마다 현재 버전보다 높은 버전 번호로 새 마이그레이션을 생성하면 됩니다. 다음에 Flyway가 시작되면 이를 찾아서 데이터베이스를 업그레이드합니다.

 

 

First Steps: Command-line

Flyway Command-line 도구를 시작하고 실행하는 방법을 설명합니다. 

사전준비

Flyway 명령줄 도구를 다운로드하고 압축을 풉니다. Community, Teams, Enterprise 버전이 있습니다. 본 문서에서는 Windows용 Community 버전을 다운로드 합니다.

다운로드 : downloading the Flyway Command-line Tool 

Flyway 설정

Flyway를 다운로드하여 압축해제한 디렉토리로 이동합니다.

이동한 디렉토리 하위의 conf 디렉토리에 있는 flyway.conf 파일을 아래와 같이 설정합니다. 

기본적으로 내장되어 있는 H2 DB의 환경설정 부분입니다. 각자의 DB에 맞는 환경 설정을 하면 됩니다.

jdbc로 DB와 연결되므로 사용하는 DB에 맞는 jdbc 드라이버를 flyway 홈디렉토리 밑에 drivers 디렉토리에 가져다 놓으면 됩니다.

flyway.url=jdbc:h2:file:./foobardb
flyway.user=SA
flyway.password=

 

참고) mysql DBdml flywaydb 데이터베이스에 접속하는 경우

flyway.url=jdbc:mysql://<ip_address>:3606
flyway.schemas=flyway
flyway.user="username"
flyway.password="******"

Baseline

데이터베이스의 기준을 설정합니다.

baseline은 flyway의 기준을 지정하는 명령어입니다.

 

flyway baseline 명령어를 실행하면 아래 내용을 볼수 있습니다.

"Successfully baselined schema with version: 1" 이 있는데 이는 flyway migrate 의 version을 최초 1로 설정한 것입니다.

flyway-9.17.0> flyway baseline
Flyway Community Edition 9.17.0 by Redgate
See release notes here: https://rd.gt/416ObMi

Database: 
Creating Schema History table `flyway`.`flyway_schema_history` with baseline ...
Successfully baselined schema with version: 1

위의 그림처럼 flyway_schema_history 테이블을 생성하고 version 1 의 baseline을 설정합니다.

flyway info를 수행하면  관련 정보를 볼 수 있습니다.

flyway-9.17.0> flyway info

Flyway Community Edition 9.17.0 by Redgate
See release notes here: https://rd.gt/416ObMi

+----------+---------+-----------------------+----------+---------------------+----------+----------+
| Category | Version | Description           | Type     | Installed On        | State    | Undoable |
+----------+---------+-----------------------+----------+---------------------+----------+----------+
|          | 1       | << Flyway Baseline >> | BASELINE | 2023-04-28 13:51:24 | Baseline | No       |
+----------+---------+-----------------------+----------+---------------------+----------+----------+

A Flyway report has been generated here: report.html

 

만약, migrate할 sql 파일명을 V1__ 로 시작되는 파일명으로 작성했을 경우, version이 1로 동일하기 때문에 V1__ 로 시작하는 파일의 sql은 수행되지 않습니다. 그러므로 아래 명령어와 같이 -baselineVersion=0 으로 지정하는 것이 좋습니다.

 

flyway-9.17.0> flyway baseline -baselineVersion=0

## 실행결과
Flyway Community Edition 9.17.0 by Redgate
See release notes here: https://rd.gt/416ObMi

Database: jdbc:mysql://dept-ssgd-aurora-an2-dev.cluster-cktyv4o7rx0c.ap-northeast-2.rds.amazonaws.com:3606/flyway (MySQL 8.0)
Creating Schema History table `flyway`.`flyway_schema_history` with baseline ...
Successfully baselined schema with version: 0


flyway-9.17.0> flyway info

## 실행결과
Flyway Community Edition 9.17.0 by Redgate
See release notes here: https://rd.gt/416ObMi

+----------+---------+-----------------------+----------+---------------------+----------+----------+
| Category | Version | Description           | Type     | Installed On        | State    | Undoable |
+----------+---------+-----------------------+----------+---------------------+----------+----------+
|          | 0       | << Flyway Baseline >> | BASELINE | 2023-04-28 13:51:24 | Baseline | No       |
+----------+---------+-----------------------+----------+---------------------+----------+----------+

A Flyway report has been generated here: report.html

 

 

 

baseline 재설정
마이그레이션이 많은 경우 기본 마이그레이션을 재설정하는 것이 좋습니다. 이렇게 하면 오래되고 관련이 없을 수 있는 많은 스크립트를 처리하는 오버헤드를 줄일 수 있습니다.

마이그레이션 생성

마이그레이션 파일은 /sql 디렉터리에 "V + (version표기) + __ + ... + .sql" 형식으로 파일을 생성합니다.

여기서 대문자 "V"는 version이라는 단어를 의미하고 "version표기"은 version 정보입니다.

version형식은 일반적인 표기와 동일합니다. 예를 들면 1.1.1 등의 형식입니다. migrate은 버전형식의 오름차순으로 수행합니다.

 

migrate 파일형식 : (V + version표기+ __filename.sql)

  • V : version
  • version표기 : 예시) 1, 1.1, 2, 2.1 등
  • __ : 연속된 언더바 2개
  • filename : 임의의 파일명
  • .sql = 파일확장자

예시 : V1__Create_person_table.sql 

 

V1__Create_person_table.sql 이라는 첫 번째 마이그레이션을 만듭니다. V1 다음의 __는 언더바가 2개입니다. 반드시 2개이어야 하며 V는 반드시 대문자를 써야 합니다. 만든 파일을 flyway 홈디렉토리 및에 sql 디렉토리에 위치시킵니다.

create table PERSON (
    ID int not null,
    NAME varchar(100) not null
);

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

Flyway 마이그레이션을 수행합니다. 

주의할 점은 baseline을 설정하지 않고 flyway migrate 명령어를 수행할 때 데이터베이스에 table이 존재하면 "non-empty schema" 오류가 발생합니다.

스키마에 테이블이 존재할 경우에는 flyway baseline 또는  flyway migrate -baselineOnMigrate=true 명령어를 수행해야 합니다. baselineOnMigrate=true 옵션은 baseline을 설정하고 migrate을 수행합니다.

단, baseline을 수행할 경우에는 version 1의 BASELNE이 설정되므로 "V1__"으로 시작하는 sql 파일이 존재할 경우에 동일한 버전 오류가 발생하니 sql파일명을 V1 이상의 버전으로 설정해야 합니다.

또는 flyway migrate -baselineOnMigrate=true -baselineVersion=0 명령어를 수행하여 baseline의 version을 0으로 설정합니다.

flyway-9.16.3> flyway migrate

 

모든 것이 잘 되었다면 다음 출력이 표시됩니다.

Flyway Community Edition 9.16.3 by Redgate
See release notes here: https://rd.gt/416ObMi

Database: jdbc:h2:file:./foobardb (H2 2.1)
Schema history table "PUBLIC"."flyway_schema_history" does not exist yet
Successfully validated 1 migration (execution time 00:00.014s)
Creating Schema History table "PUBLIC"."flyway_schema_history" ...
Current version of schema "PUBLIC": << Empty Schema >>
Migrating schema "PUBLIC" to version "1 - Create person table"
Successfully applied 1 migration to schema "PUBLIC", now at version v1 (execution time 00:00.022s)

두번째 마이그레이션 추가

 /sql 디렉토리에 V2__Add_people.sql 두 번째 마이그레이션을 추가합니다.

insert into PERSON (ID, NAME) values (1, 'Axel');
insert into PERSON (ID, NAME) values (2, 'Mr. Foo');
insert into PERSON (ID, NAME) values (3, 'Ms. Bar');

 

Flyway를 실행하여 데이터베이스를 마이그레이션합니다.

flyway-9.16.3> flyway migrate

아래와 같은 결과가 표시됩니다.

Flyway Community Edition 9.16.3 by Redgate
See release notes here: https://rd.gt/416ObMi

Database: jdbc:h2:file:./foobardb1 (H2 2.1)
Successfully validated 2 migrations (execution time 00:00.019s)
Current version of schema "PUBLIC": 1
Migrating schema "PUBLIC" to version "2 - Add people"
Successfully applied 1 migration to schema "PUBLIC", now at version v2 (execution time 00:00.026s)

Flyway 실행정보를 보려면 flyway info 명령어를 수행합니다. flyway 버전, type, 수행시간, 수행상태 등의 수행 내역을 보여줍니다.