Рубрики
Без рубрики

Ремонт Пролетного Строения С Пружинным Загрузчиком

Узнайте, как восстановиться после неудачной миграции Flyway с помощью Spring Boot.

Автор оригинала: baeldung.

1. Обзор

Миграция по пролетным путям не всегда идет по плану. В этом уроке мы рассмотрим варианты восстановления после неудачной миграции .

2. Настройка

Давайте начнем с базового проекта Spring Boot, настроенного для Flyway. Он имеет flyway-core , spring-boot-starter-jdbc , и flyway-maven-plugin | зависимости.

Для получения более подробной информации о конфигурации, пожалуйста, обратитесь к нашей статье, в которой представлен Flyway .

2.1. Конфигурация

Во-первых, давайте добавим два разных профиля. Это позволит нам легко выполнять миграции с различными ядрами баз данных:


    h2
    
        true
    
    
        
            com.h2database
	    h2
        
    


    postgre
    
        
            org.postgresql
            postgresql
        
    

Давайте также добавим файлы конфигурации базы данных 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-postgres.properties :

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

Примечание: Мы можем либо настроить конфигурацию PostgreSQL в соответствии с уже существующей базой данных, либо использовать файл docker-compose в примере кода .

2.2. Миграции

Давайте добавим наш первый файл миграции, V1_0__add_table.sql :

create table table_one (
  id numeric primary key
);

Теперь давайте добавим второй файл миграции, содержащий ошибку, V1_1__add_table.sql:

create table table_one (
  id numeric primary key
);

Мы специально допустили ошибку, используя одно и то же имя таблицы. Это должно привести к ошибке миграции Flyway.

3. Запустите миграцию

Теперь давайте запустим приложение и попробуем применить миграции.

Сначала для профиля по умолчанию h2 :

mvn spring-boot:run

Затем для профиля postgres :

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 | Failed  |
+-----------+---------+-------------+------+---------------------+---------+

Но когда мы проверяем состояние 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  |                     | Pending |
+-----------+---------+-------------+------+---------------------+---------+

Разница заключается в том, что PostgreSQL поддерживает транзакции DDL , в то время как другие, такие как H2 или MySQL, этого не делают. В результате PostgreSQL смог откатить транзакцию для неудачной миграции . Давайте посмотрим, как эта разница влияет на вещи, когда мы пытаемся восстановить базу данных.

3.2. Исправьте ошибку и повторите миграцию

Давайте исправим файл миграции V1_1__add_table.sql , исправив имя таблицы из table_one в table_two.

Теперь давайте попробуем запустить приложение еще раз:

mvn spring-boot:run -Ph2

Теперь мы замечаем, что миграция H2 завершается неудачей с:

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

Flyway не будет повторно запускать миграцию версии 1.1 до тех пор, пока для этой версии уже существует неудачная миграция.

С другой стороны, профиль postgres успешно запущен. Как упоминалось ранее, из-за отката состояние было чистым и готовым применить исправленную миграцию.

Действительно, запустив mvn flyway:info-Postgres , мы можем увидеть, что обе миграции были применены с Успехом . Итак, в заключение, для PostgreSQL все, что нам нужно было сделать, это исправить наш сценарий миграции и повторно запустить миграцию.

4. Вручную восстановите состояние базы данных

Первый подход к восстановлению состояния базы данных заключается в том, чтобы вручную удалить запись Flyway из flyway_schema_history таблицы .

Давайте просто запустим эту инструкцию SQL для базы данных:

delete from flyway_schema_history where version = '1.1';

Теперь, когда мы снова запускаем mvn spring-boot:run , мы видим, что миграция успешно применена.

Однако прямое управление базой данных может оказаться не идеальным. Итак, давайте посмотрим, какие у нас есть другие варианты.

5. Ремонт Взлетно-Посадочной полосы

5.1. Исправление неудачной миграции

Давайте двигаться вперед, добавив еще одну неработающую миграцию V1_2__add_table.sql file , запустив приложение и вернувшись в состояние, в котором у нас произошла неудачная миграция.

Другим способом восстановления состояния базы данных является использование инструмента |/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 //. Однако на этот раз миграция не будет выполнена. Только контрольная сумма записи версии 1.1 в таблице flyway_schema_history будет обновлена, чтобы отразить обновленный файл миграции.

Запустив приложение снова после ремонта, мы замечаем, что приложение теперь успешно запускается.

Обратите внимание, что в этом случае мы использовали flyway:repair via Maven. Другой способ-установить инструмент командной строки Flyway и запустить flyway repair . Эффект тот же: flyway repair удалит неудачные миграции из таблицы flyway_schema_history и перестроит контрольные суммы уже примененных миграций .

6. Обратные вызовы Flyway

Если мы не хотим вмешиваться вручную, мы могли бы рассмотреть подход к автоматической очистке неудачных записей из flyway_schema_history после неудачной миграции . Для этой цели мы можем использовать после ошибки миграции |/Flywaycallback .

Сначала мы создаем файл обратного вызова SQL db/callback/после переноса ошибки__repair.sql :

DELETE FROM flyway_schema_history WHERE success=false;

Это автоматически удалит любую неудачную запись из истории состояния взлетно-посадочной полосы при возникновении ошибки миграции.

Давайте создадим конфигурацию application-callbacks.properties profile, которая будет включать папку db/callback в списке местоположений Flyway:

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

Как и ожидалось, миграция завершилась неудачно, но после ошибки миграции обратный вызов запустился и очистил flyway_schema_history .

Достаточно просто исправить файл V1_3__add_table.sql migration и снова запустить приложение, чтобы применить его к исправленной миграции.

7. Резюме

В этой статье мы рассмотрели различные способы восстановления после неудачной миграции Flyway.

Мы видели, как такая база данных, как PostgreSQL, то есть та, которая поддерживает транзакции DDL, не требует дополнительных усилий для восстановления состояния базы данных Flyway.

С другой стороны, для баз данных типа H2 без этой поддержки мы видели, как Ремонт пролета можно использовать для очистки истории пролета и в конечном итоге применить исправленную миграцию.

Как всегда, полный код доступен на GitHub .