如何使用 Flyway 回滚迁移?

Posted

技术标签:

【中文标题】如何使用 Flyway 回滚迁移?【英文标题】:How to roll back migrations using Flyway? 【发布时间】:2011-06-24 23:07:13 【问题描述】:

MyBatis 迁移将每个 SQL 文件分成两部分:

    一个用于向前迁移一个版本 一个用于迁移回一个版本

如何使用Flyway回滚版本?

【问题讨论】:

doh,我希望像这样:如何 rick roll :) 【参考方案1】:

虽然 Flyway 支持回滚(仅作为商业功能),但不鼓励使用它:

https://flywaydb.org/documentation/command/undo

虽然撤消迁移的想法很好,但不幸的是它有时在实践中会失败。一旦发生破坏性更改(删除、删除、截断……),您就会开始陷入麻烦。即使你不这样做,你最终也会创建用于恢复备份的自制替代方案,这也需要进行适当的测试。

撤消迁移假定整个迁移成功,现在应该撤消。这对于在没有 DDL 事务的数据库上失败的版本化迁移没有帮助。为什么?迁移可能随时失败。如果您有 10 条语句,则第 1 条、第 5 条、第 7 条或第 10 条可能会失败。根本没有办法提前知道。相反,撤消迁移是为了撤消整个版本化迁移而编写的,在这种情况下无济于事。

我们认为更可取的另一种方法是保持数据库与当前部署在生产环境中的所有代码版本之间的向后兼容性。这样,失败的迁移就不是灾难。旧版本的应用程序仍然与数据库兼容,因此您可以简单地回滚应用程序代码,调查并采取纠正措施。

这应该辅以适当的、经过充分测试的备份和恢复策略。它独立于数据库结构,一旦经过测试并证明可以工作,任何迁移脚本都无法破坏它。为获得最佳性能,如果您的基础架构支持这一点,我们建议您使用底层存储解决方案的快照技术。尤其是对于较大的数据量,这可能比传统的备份和恢复快几个数量级。

【讨论】:

您最好的选择当然是使用适当支持 DDL 事务的数据库,例如 PostgreSQL。这样,数据库将负责为您清理混乱。 你误解了我的问题的重点。我并不是说我想在事务中间回滚以防万一失败。我是说客户拥有第 4 版的数据库,我想将他回滚到第 2 版。 另一个用例是在新功能出现问题时回滚(生命)系统 另一个用例是在一些迁移之前的分支上工作。然后我想在其他分支工作。回滚这些迁移是必须的,否则代码会中断。 我喜欢 Flyway 进行迁移,但我发现不实施回滚的论据相当蹩脚。正如@mirelon 之前所述,在实际用例中回滚是必须具备的。【参考方案2】:

从 Flyway 5.0 开始支持此功能。遗憾的是,它只是一个商业功能。

https://flywaydb.org/documentation/command/undo

【讨论】:

鉴于***.com/a/4959332/14731 中提到的警告仍然适用,这不会让您走得太远。不过,很高兴知道这是添加的。也许他们将来会找到一种方法来消除其中的一些限制。 这些警告已在最新版本中进行了修订。请参阅相关的commit。【参考方案3】:

我假设您需要回滚策略,例如合作伙伴在生产阶段失败,他的部署对于您的发布至关重要。

您可以将 flyway SQL 脚本命名为:V.000_.sql

现在您可以离开 V.998_rollback.sql 以进行回滚 并让 V.999_reenroll.sql 重新注册。

在您的 CI/CD 环境中,您在部署作业之后还需要 2 个作业(手动触发)。一种用于回滚,它运行包括飞路迁移在内的回滚过程。其他用于重新注册。 您只需要关心 flyway 中的目标配置。 对于您的部署作业,您的目标应该是 .997 对于您的回滚作业 .998

当您开始新版本时,请确保您不会运行旧版本的回滚/重新注册脚本。

如前所述,推荐使用备份和恢复策略。

(抱歉英语不好)

【讨论】:

以上是关于如何使用 Flyway 回滚迁移?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 flyway 跳过特定的迁移?

最佳实践:使用后如何修改flyway迁移脚本

如何将 Flyway 迁移与单个架构和多个项目一起使用

使用flyway迁移脚本时如何从文件中填写表格

flyway mysqldump迁移

使用 Flyway 迁移存储过程