У меня проблема с выполнением Doctrine Migrations в подобных средах с использованием LoadBalancer.
Шаги для освобождения:
- Отмена регистрации узла в балансировщике нагрузки (ELB).
- Обновление кода на узле
- Выполнение необходимых команд (с выполнением миграции доктрины).
- Регистрация узла в балансировщике нагрузки (ELB).
Но с первым узлом все в порядке, мы выпускаем новый код и выполняем миграцию.Но если миграция содержит добавление столбцов в таблицы без значения по умолчанию, у нас есть проблема в следующих узлах.Поскольку в следующих узлах у нас нет обновленного кода (с обновленными метаданными ORM).
В качестве примера мы приведем миграцию:
ALTER TABLE customers ADD blocked BOOLEAN DEFAULT NULL;
UPDATE customers SET blocked = FALSE;
ALTER TABLE customers ALTER blocked SET NOT NULL;
На первом узле - все в порядке.У нас есть новая структура таблицы и обновленные метаданные сущности.Но следующие узлы не могут вставить запись клиенту, потому что их метаданные не знают поля blocked
.
Как мы работаем в этом сценарии (без простоя):
- Добавить первую миграцию только для добавления столбца и первого обновления для установленного значения по умолчанию.
- Код должен установить значение по умолчанию в конструкторе объекта.
- Добавить вторую миграцию для удаления по умолчаниюзначение и установить не нуль.
В результате мы имеем следующий поток.
Release # 1
ALTER TABLE customers ADD blocked BOOLEAN DEFAULT NULL;
UPDATE customers SET blocked = FALSE;
Release # 2
UPDATE customers SET blocked = FALSE WHERE blocked IS NULL;
ALTER TABLE customers ALTER blocked SET NOT NULL;
Выпуск № 1 и выпуск № 2 - разные выпуски.
Но это очень сложно для управления, если у нас есть устаревший код, когда команда проводит рефакторинг кода.Потому что мы должны знать обо всех PR - какой PR должен быть объединен после x.x.x
релиза.
Я думаю, что функциональность, которая содержит пост-релиз, должна решить эту проблему (возможно, не исправить имена, извините).В качестве примера:
$ ./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 или сторонняя библиотека поддерживают эту функцию.А может я не правильно думаю и у нас упрощенное решение?