【发布时间】:2022-11-11 17:33:33
【问题描述】:
我正在使用 CI CD 管道部署 liquibase 脚本。在某些情况下,liquibase 变更集事务可能需要很长时间,并且在此期间 pod 可能会关闭。例如,变更集将一个新的非空列添加到已有一百万条记录的现有表中。默认值将添加到表的现有行中。我想知道在使用默认值更新几行后 pod 关闭时会发生什么。
【问题讨论】:
标签: kubernetes jenkins liquibase flyway cicd
我正在使用 CI CD 管道部署 liquibase 脚本。在某些情况下,liquibase 变更集事务可能需要很长时间,并且在此期间 pod 可能会关闭。例如,变更集将一个新的非空列添加到已有一百万条记录的现有表中。默认值将添加到表的现有行中。我想知道在使用默认值更新几行后 pod 关闭时会发生什么。
【问题讨论】:
标签: kubernetes jenkins liquibase flyway cicd
答案在某种程度上取决于您的数据库,并且它实际上是否已被杀死。 liquibase 试图做的是:
首先,将databasechangeloglock表更新为“locked”并提交
然后,对于每个变更集
最后,将 databasechangeloglock 表更新为“未锁定”并提交。
如果 pod 在该过程中被随机杀死,则影响将取决于它被杀死的确切位置以及正在发生的事情。
时间百分比在上面的#2 中,所以这很可能是它被杀死的地方。因为我们试图在一个事务中运行,当连接被切断时,数据库应该自动回滚事务。但:有些语句是自动提交的,可能会搞砸并让事情部分完成。
如果您有一个变更集,它只是对所有行进行更新并且在此期间 pod 被杀死,大多数数据库可以回滚该更新并且不会更新任何行,并且下次 liquibase 运行时它知道变更集没有已运行,它将重试更新。
如果您有一个添加列并更新行并且在更新期间被终止的变更集,则大多数数据库将提交“添加列”,因此回滚只会撤消值的更新。而且由于变更集没有标记为已运行,下一次更新将尝试再次运行它,并且将失败并出现“列已存在”异常。
出于这个原因,最好对每个 changeSet 进行一次更改,除非它们都可以在单个事务中运行。
如果它在该过程中的其他任何地方失败,它仍然是相同的“数据库将回滚当前事务,因此这取决于当前事务中发生的情况”。
无论它在 changeSet 中的哪个位置失败,您都会遇到未运行“解锁 databasechangeloglock 表”步骤的问题。下一次 liquibase 运行将阻塞,直到它被解锁。对于托管 CICD 系统,基础设施在“确保只有一个版本的 liquibase 正在运行”方面比 liquibase 对 databasechangeloglock 表所做的工作做得更好,因此您可以添加“liquibase unlock”作为 pod 的第一步安全的。
【讨论】: