这是一个艰难的。
v1.1
有一个索引为i的表。v2.1
也包含此表和索引。发现了一个错误,在v1.1.0.1
我们更改了代码,因此决定放弃索引。
我们为v2.1
,v2.1.0.6
创建了相应的修补程序。
客户应用了补丁v1.1.0.1
,几周后升级到v2.1
(没有补丁6)
由于v2.1
代码库对索引的性能更好,因此我们有一个“损坏的”应用程序。
Liquibase或Flyway可以处理这种情况吗?
答案 0 :(得分:3)
我猜这些问题更具组织性,而非工具特定性。如果您支持多个版本(分支1.0和更新的2.0)并为两者提供补丁(这是完全合法的方法 - 请不要误解我的意思)您可能必须提供所有这些版本的升级说明,也许是矩阵,显示您可以从哪个版本(以及您不能做的)。
我刚刚升级了旧版Atlassian的Jira Bugtracker,并且必须发现它们确实提供了所有版本的升级说明。
这意味着从一个版本到另一个版本最终到达最新版本(我在版本4.x并且想要转到最新的5.x)并遵守其间的所有升级说明。 (顺便说一句,我跳过所有这些并将其设置为一个完整的全新安装以避免这种情况。)
只是为了给您一个印象,这是一个显示所有这些升级说明的页面: https://confluence.atlassian.com/display/JIRA/Important+Version-Specific+Upgrade+Notes
所以我猜你可以提供一个小脚本来重新创建索引,如果有人想从版本1.1.0.1
转到2.1
并在升级笔记中说明需要应用它。
既然你问liquibase(或flyway)是否可以支持这个,也许有必要提一下liquibase(我只知道liquibase)有一个名为preConditions
的东西。这意味着您可以根据(例如)索引存在<indexExists>
的事实运行变更集(相应的sql)。
如果索引丢失,这可能有助于重新创建索引。
但是,由于版本2.1已经发布(在知道索引可能在将来的错误修复中被删除之前),因此没有机会将此功能添加到版本2.1的升级过程中。
答案 1 :(得分:2)
Liquibase可以很好地处理分支上的drop index变化,但是因为你要从包含代码的版本(drop index change)变成一个不期望你最终会破坏应用程序状态的版本。
使用liquibase,更改完全相互独立,并且与任何版本控制无关。您可以将liquibase changelog视为有序更改列表,使每个更改都具有唯一标识符。当您进行更新时,liquibase会依次检查每个更改,看看它是否已经运行,如果没有,则运行它。
任何“版本控制”纯粹属于您的代码库和分支方案,liquibase并不关心。
想象一下,你从1.1.0版开始看起来像:
部署1.1.0时,客户数据库将知道已运行的更改a,b和c。
你的v2.1在更改日志文件的末尾有新的更改集,所以它看起来像:
并且所有2.1客户数据库都知道应用了a,b,c,x,y,z。
使用更改集d创建1.1.0.1会丢弃索引时,最终会在1.1.0.1分支中使用此更改日志:
但是当您将1.1.0.1客户升级到2.1时,liquibase只是将(a,b,c,x,y,z)的已定义变更集与(a,b,c,d)的已知变更集进行比较,运行x,y,z。它并不关心d已经存在变化集,它对此没有任何作用。
liquibase diff支持可以用作一些健全性检查,并且能够报告与某些“正确”数据库相比缺少索引,但这不是您通常在生产部署中执行的操作场景。
答案 2 :(得分:0)
答案可能有点晚,但我会分享我的经验。我们在项目中也遇到了同样的问题。我们以下一个方式处理它:
由于我们项目中的版本不经常发布,因此我们在liquibase中标记了每个变更集context。该值是确切的版本迁移(如 v6.2.1-v6.2.2 )。我们通过jndi属性将值传递给liquibase,因此客户能够指定它们。因此,在升级期间,客户负责为每次升级设置迁移范围的正确值。 Liquibase上下文可以接受值列表。所以最后,上下文看起来像这样:
{{1}}