使用 Spring 引导的 Flyway 迁移错误详细信息

Flyway migration error details with Spring Boot

我们有一个项目使用 Spring Boot 和 flyway。

当我们 运行 迁移失败时,日志级别全部设置为 DEBUG,我们只收到这些消息:

[DEBUG] org.flywaydb.core.internal.command.DbValidate - Validating migrations ...
[DEBUG] org.flywaydb.core.internal.scanner.Scanner - Filtering out resource: db/migration/V1/V1_202103081030__account.sql (filename: V1_202103081030__account.sql)
[DEBUG] org.flywaydb.core.internal.scanner.Scanner - Filtering out resource: db/migration/V1/V1_202103081040__place.sql (filename: V1_202103081040__place.sql)
[DEBUG] org.flywaydb.core.internal.scanner.Scanner - Filtering out resource: db/migration/V1/V1_202103151608__document.sql (filename: V1_202103151608__document.sql)
[DEBUG] org.flywaydb.core.Flyway - Memory usage: 147 of 254M
[ERROR] org.springframework.boot.web.embedded.tomcat.TomcatStarter - Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'openEntityManagerInViewInterceptorConfigurer' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration$JpaWebConfiguration.class]: Unsatisfied dependency expressed through method 'openEntityManagerInViewInterceptorConfigurer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'openEntityManagerInViewInterceptor' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration$JpaWebConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
...
[INFO ] org.apache.catalina.core.StandardService - Stopping service [Tomcat]
...
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation

没有关于失败原因的更多详细信息(查询失败、校验和不匹配,...)。

我查看了 spring.flyway 应用程序属性,但没有发现任何有用的信息。

我们应该怎么做才能在服务器启动时在我们的日志中显示 flyway root 错误?

编辑:明确地说,问题不是故障本身(在 Flyway 类 中设置断点可以揭示源错误)。问题是日志中缺少错误详细信息。

我不知道具体是什么失败了,但这可能会帮助您指明正确的方向。

  1. 打开 DbValidate(flyway class)。 (如果需要,请下载资源)
  2. 在第186-187行的else语句中打断点
  3. 再次启动服务器

这至少会告诉您哪个文件失败了。

然后您可以向 Flyway 项目提出增强请求,以获得更好的错误报告。

好吧,可能会发生很多事情,但一个可能的原因是您在应用迁移文件后更改了它。我将按用例进行解释:

假设在时间 X 有 2 个迁移(技术上在 SQL 文件中实现):A1 和 A2。

这是您第一次提交 A1 和 A2,当您 运行 应用程序时,flyway 在数据库中创建一个特殊的 table 以查看已经应用了哪些迁移。显然,在时间 X 那里还没有迁移,所以它创建一个 table,应用 A1 和 A2,并在 table 中添加 2 条记录。这些记录除其他事项外应包括校验和。简单的说你可以把这些checksum看成是对应A1和A2内容的哈希值(类似sha1)

到目前为止一切顺利,现在在您引入新的迁移文件 A3 时快进时间(到时间 Y)。

当您重新部署应用程序时,flyway 会检查已应用的 A1 和 A2 是否未更改,然后才会应用新的迁移。

现在,此验证确实是应用迁移的先决条件 A3 检查这些散列 - 校验和。这是合理的——因为如果你碰巧改变了 A1 或 A2——flyway 应该做什么——它如何保证迁移按预期工作?

您还可以阅读 in the official flyway documentation 有关此验证的内容,但是,我相信您已经明白了。有人通过更改您现有的迁移之一更改了校验和,并尝试重新部署应用程序。

简而言之,应用迁移文件后 - 无法在源树中更改它

现在我描述的场景是一种可能的场景,一般来说,你甚至不必创建迁移 A3,更改现有迁移并尝试重新启动就足够了运行 应用程序 - 验证将失败。

我遇到了同样的问题,发现它与我使用的 Flyway 版本有关(Spring Boot 2.4.3,它使用 Flyway 7.1.1)。这是一个已知问题 2987 - Display all validate messages in exceptions, fixed in Flyway 7.2.0

他们推荐 运行 flyway validate -outputType=json 作为获得详细错误消息的解决方法。我试过了,但仍然没有收到详细的错误消息。

对我有用的解决方案是升级到 Flyway 7.2.0,方法是在我的 pom 文件中指定版本:

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>7.2.0</version>
</dependency>