如何处理以前有效的 Flyway 迁移变得无效

How to deal with previously valid Flyway migrations that became invalid

我有一个 Spring 启动应用程序,它使用 Flyway 在 Postgres 中进行数据库迁移。

它现在已经四岁了,所以我们正在谈论 Flyway 4.0.3、Spring Boot 1.3.x 和 Postgres 9.x。版本可能会升级,但我想在升级之前解决所有现有问题。

同时,Postgres 升级到高于 9.x。不幸的是,一些现有的迁移变得过时了,因为它们包含不推荐使用的语法。因此,现在使用新数据库(即在开发环境中)启动应用程序会导致这些迁移失败。在生产中它很好,因为这些迁移已经应用并且不会再次应用。

我很好奇解决此问题的最佳做法是什么。我不能直接修复现有迁移中的语法,因为这会导致生产环境中的校验和失败。我知道 repair 是一回事,但我不确定它是如何工作的以及如何将它与 Spring Boot.

一起使用

失败SQL:

UPDATE config
SET (description) = 'my description'
WHERE ...

正确SQL:

UPDATE config
SET description = 'my description'
WHERE ...

错误:

Message    : ERROR: source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression

编辑 24/04/2020 Spring 引导解决方案:

在 Grant Fitchey 在下面发布了关于如何使用 repair 的正确答案之后,我将添加我是如何使用 Spring Boot 来具体做到这一点的。我刚刚创建了一个 FlywayMigrationStrategy 的 bean,它调用 repair 在调用 migrate 之前:

@Bean
public FlywayMigrationStrategy cleanMigrateStrategy() {
    return flyway -> {
        flyway.repair();
        flyway.migrate();
    };
}

将此部署到生产环境时,在启动期间修复了 Postgres 中 schema_versions table 中的校验和。在另一个版本中,我将再次删除 flyway.repair(); 行,否则显然会产生应用无效迁移的风险。

您正在寻找修复选项。我不知道如何通过 spring 引导直接调用它,但是 documentation is here。这应该可以准确地满足您的需求。

因此,在这种情况下,第一步是修复迁移,以便它们在开发环境中正确执行。现在开发应该没问题,flyway应该迁移成功了。

在生产环境中,您现在应该会收到验证错误,因为校验和不同。 Flyway 修复将 'repair' 模式历史记录 table 以便它存储的校验和与磁盘上的新校验和匹配,因此 flyway 验证再次通过。 具体来说,flyway repair 正在做的是使模式历史记录 table 与您在磁盘上的内容相匹配。它将应用迁移的所有校验和更新为您在磁盘上的校验和(因此,只有在您确信更改相同时才使用它)。它还从 table 中删除所有失败的迁移条目(同样,只有在您自己清理数据库后才使用它)。