如何从3号航站楼直接升级到5号航道

Dyl*_*rts 6 flyway

处理许多客户在许多生产环境中部署的产品.它包括至少一个Spring Boot应用程序.

我们使用flyway进行数据库模式迁移.从Spring Boot 1.5.x升级到2.0.x已将我们的flyway版本从3.x升级到5.x.

Spring Boot迁移指南简单地说是在引导升级之前升级到flyway 4.但是,这需要我们的所有客户在升级到最新版本之前进行中间升级.

所以,问题是:如何将从飞路3直接升级到迁飞5?

Stu*_*uck 7

步骤 0。

升级到 spring boot v2.1(然后隐式升级到 flyway 5)。

第1步。

由于schema_version在 flyway 3.x 中使用,让新的 flyway 版本知道他们应该继续使用这个表。:

# application.yml
spring.flyway.table: schema_version # prior flyway version used this table and we keep it
Run Code Online (Sandbox Code Playgroud)

第2步。

src/main/ressources/db/migration/flyway_upgradeMetaDataTable_V3_to_V4.sql根据您使用的方言创建用于升级元表的文件。

几种方言的更新脚本见https://github.com/flyway/flyway/commit/cea8526d7d0a9b0ec35bffa5cb43ae08ea5849e4#diff-b9cb194749ffef15acc9969b90488d98

这是 postgres 的一个,假设飞行表名称是schema_version

-- src/main/ressources/db/migration/flyway_upgradeMetaDataTable_V3_to_V4.sql
DROP INDEX "schema_version_vr_idx";
DROP INDEX "schema_version_ir_idx";
ALTER TABLE "schema_version" DROP COLUMN "version_rank";
ALTER TABLE "schema_version" DROP CONSTRAINT "schema_version_pk";
ALTER TABLE "schema_version" ALTER COLUMN "version" DROP NOT NULL;
ALTER TABLE "schema_version" ADD CONSTRAINT "schema_version_pk" PRIMARY KEY ("installed_rank");
UPDATE "schema_version" SET "type"='BASELINE' WHERE "type"='INIT';
Run Code Online (Sandbox Code Playgroud)

第 3 步。

创建 Java 文件 your.package/FlywayUpdate3To4Callback.java

请注意,这会执行以下操作:

  • 运行步骤 2 中的 sql 脚本
  • 称呼 Flyway.repair()
// FlywayUpdate3To4Callback.java
package your.package;

import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;

import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.callback.Callback;
import org.flywaydb.core.api.callback.Context;
import org.flywaydb.core.api.callback.Event;
import org.flywaydb.core.api.configuration.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@Order(HIGHEST_PRECEDENCE)
@Slf4j
public class FlywayUpdate3To4Callback implements Callback {
    private final Flyway flyway;

    public FlywayUpdate3To4Callback(@Lazy Flyway flyway) {
        this.flyway = flyway;
    }

    private boolean checkColumnExists(Configuration flywayConfiguration) throws MetaDataAccessException {
        return (boolean) JdbcUtils.extractDatabaseMetaData(flywayConfiguration.getDataSource(),
                callback -> callback
                        .getColumns(null, null, flywayConfiguration.getTable(), "version_rank")
                        .next());
    }

    @Override
    public boolean supports(Event event, Context context) {
        return event == Event.BEFORE_VALIDATE;
    }

    @Override
    public boolean canHandleInTransaction(Event event, Context context) {
        return false;
    }

    @Override
    public void handle(Event event, Context context) {
        boolean versionRankColumnExists = false;
        try {
            versionRankColumnExists = checkColumnExists(context.getConfiguration());
        } catch (MetaDataAccessException e) {
            log.error("Cannot obtain flyway metadata");
            return;
        }
        if (versionRankColumnExists) {
            log.info("Upgrading metadata table the Flyway 4.0 format ...");
            Resource resource = new ClassPathResource("db/migration/common/flyway_upgradeMetaDataTable_V3_to_V4.sql",
                    Thread.currentThread().getContextClassLoader());
            ScriptUtils.executeSqlScript(context.getConnection(), resource);
            log.info("Flyway metadata table updated successfully.");
            // recalculate checksums
            flyway.repair();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

第四步。

运行弹簧靴。

日志应显示类似于以下内容的信息消息:

...FlywayUpdate3To4Callback      : Upgrading metadata table the Flyway 4.0 format 
...FlywayUpdate3To4Callback      : Flyway metadata table updated successfully.
Run Code Online (Sandbox Code Playgroud)

学分

此答案基于 Eduardo Rodrigues 的答案,通过更改:

  • 使用Event.BEFORE_VALIDATE触发飞路回调升级飞行用3〜4。
  • 有关 application.yml 设置的更多信息
  • 提供升级sql迁移脚本


trf*_*trf 6

如果我不是地球上最后一个仍要从3升级到5的人。

问题:

我希望升级对项目中的其他开发人员来说是透明的,并且在实时应用程序上升级时不需要任何特殊的部署说明,所以我做了以下工作。

我看了第4版如何处理升级:

  • 在Flyway.java中,将调用MetaDataTableImpl.upgradeIfNecessary
  • upgradeIfNecessary检查version_rank列是否仍然存在,如果存在,则从org / flywaydb / core / internal / dbsupport / YOUR_DB /中运行一个名为upgradeMetaDataTable.sql的迁移脚本。
  • 如果执行upgradeIfNecessary,则Flyway.java运行DbRepair调用repairChecksumsAndDescriptions

这很容易手动完成,但使其透明。该应用程序是一个Spring应用程序,但不是Spring Boot应用程序,因此,当我让flyway在应用程序启动时通过依赖于flyway bean的LocalContainerEntityManagerBean构造自动在应用程序启动时运行迁移,该迁移方法将其称为init方法(在此处说明Flyway) Spring JPA2集成-是否可以进行模式验证?),因此引导的顺序为:

Flyway bean created -> Flyway migrate called -> LocalContainerEntityManager created
Run Code Online (Sandbox Code Playgroud)

解:

我将引导程序的顺序更改为:

Flyway bean created -> Flyway3To4Migrator -> LocalContainerEntityManager created
Run Code Online (Sandbox Code Playgroud)

如果需要,Flyway3To4Migrator将在其中执行schema_table更改,如果升级发生,请运行修复,然后始终运行flyway.migrate继续迁移。

Flyway bean created -> Flyway migrate called -> LocalContainerEntityManager created
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 在某些时候,我们将删除多余的Flyway3To4Migrator类,并将配置恢复为原来的样子。
  • 我从v4 Flyway jar复制了数据库的相关upgradeMetaDataTable.sql文件,并将其简化为我的表名,等等。如果需要,可以从flyway中获取模式和表名。
  • SQL脚本周围没有事务管理,您可能需要添加
  • Flyway3To4Migrator调用flyway.repair(),它比DbRepair.repairChecksumsAndDescriptions()稍微多一点,但是我们很高兴接受数据库在运行之前必须处于良好状态