我在使用LoadBalancer的类似产品的环境中执行“教义迁移”时遇到问题。
发布步骤:
但是,第一个节点一切正常,我们发布新代码并执行迁移。但是,如果迁移包含不带默认值的表添加列,则下一个节点会出现问题。因为在下一个节点中,我们没有更新的代码(具有ORM的更新的元数据)。
作为示例,我们包含迁移:
ALTER TABLE customers ADD blocked BOOLEAN DEFAULT NULL;
UPDATE customers SET blocked = FALSE;
ALTER TABLE customers ALTER blocked SET NOT NULL;
在第一个节点上-一切正常。我们具有表的新结构和实体的更新后的元数据。但是,下一个节点无法将记录插入客户,因为它们的元数据不知道blocked
字段。
在这种情况下我们的工作方式(无停机时间):
结果,我们有了下一个流程。
第1版
ALTER TABLE customers ADD blocked BOOLEAN DEFAULT NULL;
UPDATE customers SET blocked = FALSE;
第2版
UPDATE customers SET blocked = FALSE WHERE blocked IS NULL;
ALTER TABLE customers ALTER blocked SET NOT NULL;
版本1和版本2-不同的版本。
但是,如果我们在团队重构代码时拥有旧版代码,这对管理来说将非常困难。因为我们应该了解所有PR-x.x.x
发布后应该合并哪个PR。
我认为发布后包含的功能应解决此问题(抱歉,可能不正确的名称)。例如:
$ ./bin/console doctrine:migrations:migrate --pre-release
# Release all nodes.
$ ./bin/console doctrine:migrations:migrate --post-release
并且应该通过界面或注释标记迁移...
class Version000 implements PreRelease
class Version001 implements PostRelease
也许DoctrineMigrations或第三方库支持此功能。或者,也许我没有正确考虑,我们已经简化了解决方案?