如何解决 OpenShift 集群中多个 pod 中的 liquibase 等待更改日志锁定问题?

Ale*_*azy 7 database liquibase openshift spring-boot kubernetes

我们支持使用 Spring Boot 用 Ja​​va 编写并部署在 OpenShift 中的多个微服务。一些微服务与数据库通信。我们经常在单个部署中的多个 Pod 中运行单个微服务。当每个微服务启动时,它会启动 liquibase,它会尝试更新数据库。问题是有时一个 pod 在等待更改日志锁定时会失败。当这种情况发生在我们的生产 OpenShift 集群中时,我们预计其他 pod 在重新启动时会失败,因为与更改日志锁定问题相同。因此,在最坏的情况下,所有 Pod 都将等待解除锁定。

我们希望 Liquidbase 在每个 Pod 启动时自动准备我们的数据库模式。

在每个微服务中存储这个逻辑是否好?出现liquidbase changelog lock问题如何自动解决?我们是否需要将数据库准备逻辑放在单独的部署中?

所以也许我应该解释一下我的问题。在微服务架构方面运行数据库迁移的最佳方法是什么?也许我们不应该在每个 pod 中使用数据库迁移?也许最好用单独的部署来完成,或者用一些根本不在 OpenShift 中的额外 Jenkins 工作来完成?

hts*_*ame 11

当 Liquibase 在 spring-boot 应用程序部署期间启动时,它会(在非常高的级别上)执行以下步骤:

  1. 锁定数据库(在中创建记录databasechangeloglock
  2. 执行变更日志;
  3. 删除数据库锁;

因此,如果您在 Liquibase 处于步骤 1 和 3 之间时中断应用程序部署,那么您的数据库将保持锁定状态。因此,当您尝试重新部署应用程序时,Liquibase 将会失败,因为它会将您的数据库视为已锁定。

因此,您必须在再次部署应用程序之前解锁数据库。

我知道有两个选项:

  1. 清除databasechangeloglock表格或设置lockedfalse。哪个是DELETE FROM databasechangeloglockUPDATE databasechangeloglock SET locked=0
  2. 执行liquibase releaseLocks命令。您可以在此处此处找到有关它的文档。


bla*_*eij 8

我们在 Kubernetes 中将 liquibase 迁移作为 init-container 运行。在微服务中运行 Liquibase 的问题是,如果在配置的超时之前就绪探测没有成功,Kubernetes 将终止 pod。在我们的例子中,这有时发生在大型数据库迁移期间,这可能需要几分钟才能完成。Kubernetes 将终止 pod,使 DATABASECHANGELOGLOCK 处于锁定状态。使用 init-containers 你不会有这个问题。有关详细说明,请参阅https://www.liquibase.org/blog/using-liquibase-in-kubernetes

更新 请看一下这个 Liquibase 扩展,它通过使用数据库锁替换了 StandardLockService:https : //github.com/blagerweij/liquibase-sessionlock

此扩展使用 MySQL 或 Postgres 用户锁定语句,这些语句在数据库连接关闭时(例如,容器意外停止时)会自动释放。使用扩展所需的唯一事情是向库添加依赖项。Liquibase 会自动检测改进后的 LockService。

我不是图书馆的作者,但我在寻找解决方案时偶然发现了图书馆。我通过将库发布到 Maven 中心来帮助作者。目前支持 MySQL 和 PostgreSQL,但应该很容易支持其他 RDBMS。