1. 개요

이동 경로 마이그레이션이 항상 계획대로 진행되는 것은 아닙니다. 이 사용방법(예제)에서는 실패한 마이그레이션에서 복구할 수 있는 옵션을 살펴 봅니다.

2. 설정

기본 Flyway 구성 Spring Boot 프로젝트부터 시작하겠습니다. 그것은이 이동 경로 코어 , 스프링 부팅 스타터 - JDBC를 ,이동 경로 - 받는다는 - 플러그인 의존성을.

자세한 구성 정보 는 Flyway소개하는 기사를 참조하십시오 .

2.1. 구성

먼저 두 개의 서로 다른 프로필을 추가해 보겠습니다. 이렇게 하면 서로 다른 데이터베이스 엔진에 대해 마이그레이션을 쉽게 실행할 수 있습니다.

<profile>
    <id>h2</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
	    <artifactId>h2</artifactId>
        </dependency>
    </dependencies>
</profile>
<profile>
    <id>postgre</id>
    <dependencies>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
    </dependencies>
</profile>

이러한 각 프로필에 대한 Flyway 데이터베이스 구성 파일도 추가해 보겠습니다.

먼저 application-h2.properties를 만듭니다 .

flyway.url=jdbc:h2:file:./testdb;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE;MODE=MySQL;DATABASE_TO_UPPER=false;
flyway.user=testuser
flyway.password=password

그런 다음 PostgreSQL application-postgre.properties를 생성해 보겠습니다 .

flyway.url=jdbc:postgresql://127.0.0.1:5431/testdb
flyway.user=testuser
flyway.password=password

참고 : 우리는 하나 이미 존재하는 데이터베이스와 일치하도록 PostgreSQL의 구성을 조정하거나, 우리가 사용할 수있는 고정 표시기-작성 코드 샘플에서 파일을 .

2.2. 마이그레이션

첫 번째 마이그레이션 파일인 V1_0__add_table.sql을 추가해 보겠습니다 .

create table table_one (
  id numeric primary key
);

이제 오류 V1_1__add_table.sql 이 포함된 두 번째 마이그레이션 파일을 추가해 보겠습니다.

create table <span style="color: #ff0000">table_one</span> (
  id numeric primary key
);

우리는 한 동일한 테이블 이름을 사용하여 목적에 실수를했다. 이로 인해 Flyway 마이그레이션 오류가 발생합니다.

3. 마이그레이션 실행

이제 애플리케이션을 실행하고 마이그레이션을 적용해 보겠습니다.

먼저 기본 h2 프로필의 경우:

mvn spring-boot:run

그런 다음 postgre 프로필의 경우:

mvn spring-boot:run -Ppostgre

예상대로 첫 번째 마이그레이션은 성공했지만 두 번째 마이그레이션은 실패했습니다.

Migration V1_1__add_table.sql failed
...
Message    : Table "TABLE_ONE" already exists; SQL statement:

3.1. 상태 확인

데이터베이스 복구로 이동하기 전에 다음을 실행하여 Flyway 마이그레이션 상태를 검사해 보겠습니다.

mvn flyway:info -Ph2

예상대로 반환됩니다.

+-----------+---------+-------------+------+---------------------+---------+
| Category  | Version | Description | Type | Installed On        | State   |
+-----------+---------+-------------+------+---------------------+---------+
| Versioned | 1.0     | add table   | SQL  | 2020-07-17 12:57:35 | Success |
| Versioned | 1.1     | add table   | SQL  | 2020-07-17 12:57:35 | <span style="color: #ff0000">Failed</span>  |
+-----------+---------+-------------+------+---------------------+---------+

그러나 다음을 사용하여 PostgreSQL의 상태를 확인할 때:

mvn flyway:info -Ppostgre

우리는 두 번째 마이그레이션의 상태가 통지 보류 하지 못했습니다 :

+-----------+---------+-------------+------+---------------------+---------+
| Category  | Version | Description | Type | Installed On        | State   |
+-----------+---------+-------------+------+---------------------+---------+
| Versioned | 1.0     | add table   | SQL  | 2020-07-17 12:57:48 | Success |
| Versioned | 1.1     | add table   | SQL  |                     | <span style="color: #339966">Pending</span> |
+-----------+---------+-------------+------+---------------------+---------+

차이점은 PostgreSQL이 DDL 트랜잭션지원 하는 반면 H2 또는 MySQL과 같은 다른 것들은 지원 하지 않는다는 사실에서 비롯됩니다 . 결과적으로 PostgreSQL 은 실패한 마이그레이션에 대한 트랜잭션을 롤백할 수 있었습니다 . 데이터베이스를 복구하려고 할 때 이 차이가 어떻게 영향을 미치는지 봅시다.

3.2. 실수를 수정하고 마이그레이션을 다시 실행하십시오.

table_one 에서 table_two테이블 이름을 수정하여 마이그레이션 파일 V1_1__add_table.sql 을 수정 합시다.

이제 응용 프로그램을 다시 실행해 보겠습니다.

mvn spring-boot:run -Ph2

이제 H2 마이그레이션이 다음과 같이 실패함을 알 수 있습니다.

Validate failed: 
Detected failed migration to version 1.1 (add table)

이 버전에 대해 이미 실패한 마이그레이션이 존재하는 한 Flyway는 버전 1.1 마이그레이션을 다시 실행하지 않습니다 .

반면에 postgre 프로필은 성공적으로 실행되었습니다. 앞서 언급했듯이 롤백으로 인해 상태가 깨끗하고 수정된 마이그레이션을 적용할 준비가 되었습니다.

실제로 mvn flyway:info -Ppostgre 를 실행 하면 두 마이그레이션이 모두 Success 로 적용된 것을 볼 수 있습니다 . 따라서 결론적으로 PostgreSQL의 경우 마이그레이션 스크립트를 수정하고 마이그레이션을 다시 트리거하기만 하면 됩니다.

4. 수동으로 데이터베이스 상태 복구

데이터베이스 상태를 복구하는 첫 번째 방법 flyway_schema_history 테이블 에서 Flyway 항목수동으로 제거하는 것 입니다.

데이터베이스에 대해 이 SQL 문을 간단히 실행해 보겠습니다.

delete from flyway_schema_history where version = '1.1';

이제 mvn spring-boot:run을 다시 실행 하면 마이그레이션이 성공적으로 적용된 것을 볼 수 있습니다.

그러나 데이터베이스를 직접 조작하는 것은 이상적이지 않을 수 있습니다. 그럼 어떤 다른 옵션이 있는지 봅시다.

5. 플라이웨이 수리

5.1. 실패한 마이그레이션 복구

의 다른 부서 마이그레이션 추가하여 앞으로 이동하자 V1_2__add_table.sql의 파일 , 응용 프로그램을 실행하고 우리가 실패한 마이그레이션이 상태로 다시 받고.

데이터베이스 상태를 복구하는 또 다른 방법은 flyway:repair 도구를 사용하는 것 입니다. SQL 파일을 수정한 후 flyway_schema_history 테이블 을 수동으로 건드리는 대신 다음을 실행할 수 있습니다.

mvn flyway:repair

결과:

Successfully repaired schema history table "PUBLIC"."flyway_schema_history"

배후에서 Flyway는 단순히 flyway_schema_history 테이블 에서 실패한 마이그레이션 항목을 제거 합니다.

이제 flyway:info를 다시 실행 하고 마지막 마이그레이션 상태가 Failed 에서 Pending으로 변경된 것을 볼 수 있습니다 .

응용 프로그램을 다시 실행해 보겠습니다. 보시다시피 수정된 마이그레이션이 이제 성공적으로 적용되었습니다.

5.2. 체크섬 재정렬

일반적으로 성공적으로 적용된 마이그레이션을 변경하지 않는 것이 좋습니다. 그러나 우회할 수 없는 경우가 있을 수 있습니다.

따라서 이러한 시나리오 에서 파일 시작 부분에 어노테이션을 추가하여 마이그레이션 V1_1__add_table.sql변경해 보겠습니다 .

지금 애플리케이션을 실행하면 다음과 같은 "마이그레이션 체크섬 불일치" 오류 메시지가 표시됩니다 .

Migration checksum mismatch for migration version 1.1
-> Applied to database : 314944264
-> Resolved locally    : 1304013179

이것은 이미 적용된 마이그레이션을 변경했고 Flyway가 불일치를 감지하기 때문에 발생합니다.

체크섬을 재정렬 하기 위해 동일한 flyway:repair 명령을 사용할 수 있습니다 . 그러나 이번에는 마이그레이션이 실행되지 않습니다. flyway_schema_history 테이블 에 있는 버전 1.1 항목 의 체크섬만 업데이트된 마이그레이션 파일을 반영하도록 업데이트됩니다.

응용 프로그램을 다시 실행하면 복구 후 응용 프로그램이 성공적으로 시작됩니다.

이 경우 Maven을 통한 flyway:repair사용했습니다 . 또 다른 방법은 Flyway 명령줄 도구를 설치하고 Flyway 복구를 실행하는 것 입니다. 효과는 동일합니다. 이동 경로 복구flyway_schema_history 테이블 에서 실패한 마이그레이션을 제거 하고 이미 적용된 마이그레이션의 체크섬을 재정렬합니다 .

6. 플라이웨이 콜백

수동으로 개입하고 싶지 않다면 마이그레이션 실패 후 flyway_schema_history 에서 실패한 항목자동으로 정리 하는 접근 방식을 고려할 수 있습니다. 이를 위해 afterMigrateError Flyway 콜백을 사용할 수 있습니다 .

먼저 SQL 콜백 파일 db/callback/afterMigrateError__repair.sql을 생성합니다 .

DELETE FROM flyway_schema_history WHERE success=false;

이렇게 하면 마이그레이션 오류가 발생할 때마다 Flyway 상태 기록에서 실패한 항목이 자동으로 제거됩니다.

Flyway 위치 List에 db/callback 폴더를 포함 application-callbacks.properties 프로필 구성을 만들어 보겠습니다 .

spring.flyway.locations=classpath:db/migration,classpath:db/callback

이제 또 다른 깨진 마이그레이션 V1_3__add_table.sql 을 추가한 후 콜백 프로필을 포함하여 애플리케이션을 실행합니다 .

mvn spring-boot:run -Dspring-boot.run.profiles=h2,callbacks
...
Migrating schema "PUBLIC" to version 1.3 - add table
Migration of schema "PUBLIC" to version 1.3 - add table failed!
...
Executing SQL callback: afterMigrateError - repair

예상대로 마이그레이션은 실패했지만 afterMigrateError 콜백이 실행되어 flyway_schema_history 를 정리했습니다 .

V1_3__add_table.sql 마이그레이션 파일을 수정하고 애플리케이션을 다시 실행하면 수정된 마이그레이션에 적용할 수 있습니다.

7. 요약

이 기사에서는 실패한 Flyway 마이그레이션에서 복구하는 다양한 방법을 살펴보았습니다.

우리는 PostgreSQL과 같은 데이터베이스, 즉 DDL 트랜잭션을 지원하는 데이터베이스가 Flyway 데이터베이스 상태를 복구하는 데 추가 노력이 필요하지 않다는 것을 보았습니다.

반면에 이러한 지원이 없는 H2와 같은 데이터베이스의 경우 Flyway 복구를 사용하여 Flyway 기록을 정리 하고 결국 수정된 마이그레이션을 적용하는 방법을 보았습니다 .

항상 그렇듯이 전체 코드는 GitHub에서 사용할 수 있습니다 .

Persistence footer banner