【问题标题】:Spring Boot plus Liquibase: possible accidental schema rollback with obsolete changelog file?Spring Boot 加 Liquibase:可能使用过时的变更日志文件意外模式回滚?
【发布时间】:2021-10-26 19:25:09
【问题描述】:
我的团队正在考虑在我们的 Spring Boot 启动中使用 Liquibase。
我担心意外回滚架构更改。我的场景是这样的:
- 存在 Liquibase 更改日志 1、2 和 3。
- db-changelog-master.xml 提到了每个更改日志 1、2、3。
- Spring Boot 启动,liquibase 确认数据库已按要求配置。
- 对于另一个 Spring Boot 启动,用户具有过时的 Spring Boot 配置。
此配置有一个旧的 db-changelog.master.xml,仅包含变更日志 1、2。
- 当这个变种 Spring Boot 启动时,它是否会自动回滚数据库架构,以便匹配更改日志 1、2?
当用户没有显式运行回滚请求时,liquibase 是否足够聪明,不会进行隐式回滚?或者是否必须进行一些配置来防止我的情况发生?
【问题讨论】:
标签:
spring-boot
liquibase
【解决方案1】:
回答您的问题 - 不,Liquibase 不会自行回滚您的架构。
让我们回顾一下案例#4。
当 Spring-Boot 将使用过时版本的 changeLogs 启动时,Liquibase 将尝试仅执行给定的一组(过时的)changeLogs(尚未运行)。
Liquibase 只对给定变更日志集中的给定变更集感兴趣。架构中的其他所有内容都与 Liquibase 无关,例如如果 some_new_table 存在于 db 架构中,并且未在给定的 changeSet 集中进行描述,则不会删除此表。
但是
为了使它起作用,您必须记住以下几点:
-
当 Liquibase 执行 changeSet 时,它会将一些有关执行的元数据存储在 databasechangelog 表中。 Liquibase 这样做是为了关注 changeSet 的完整性,并且如果它已经执行过,则不会再次执行它
-
你必须为你的changeSets写preConditions以确保如果changeSet不应该被执行,它也不会被执行。例如:
<changeSet id="foo" author="bar">
<preConditions onFail="MARK_RAN">
<not>
<tableExists tableName="some_new_table"/>
</not>
</preConditions>
<comment>Create some_new_table table</comment>
<createTable tableName="some_new_table">
<!-- your columns here -->
</createTable>
</changeSet>
这样,Liquibase 会在尝试创建 some_new_table 之前检查它是否存在。