В данной статье речь идет о том, как правильно мигрировать схему/данные бд, если у Вас несколько инстансов приложения, которые зависят от бд.
![]() |
Многие из нас, выполняют миграцию по схеме:
Хочется заметить, что это неплохая схема, но она не работает для CI, ведь мы понимаем, что в тот момент, когда мы будем делать миграцию, часть нод все еще может работать с данными, а часть уже захочет работать с данными на основе выполненной миграции. Как же быть в этом случае? Ответ прост - нужна пошаговая схема деплоя и миграций. |
1-ый шаг
1. содержит миграцию, которая создает новое поле с именем field_name_v2
2. теперь код должен сохранять данные в оба поля (field_name и field_name_v2) Обратите внимане, в поле field_name_v2 новые данные должны сохраняться в новом формате данных
2-ой шаг
1. мигрирует данные из поля field_name в поле field_name_v2 (в новый формат)
2. теперь код начинает читать данные из поля field_name_v2 при этом все еще пишет данные в поле field_name. При этом если говорить о Entity, то setFieldName теперь устанавливает значение полю field_name_v2, а setFieldName теперь устанавливает значение полю field_name
3-ий шаг
1. содержит миграцию, которая удаляет поле field_name (т.к. оно более нигде не используется)
2. теперь код не работает с полем field_name (данные сохраняются только в поле field_name_v2).
Готово.
1. Важное правило: никаких переименований полей, т.е. мигрированное поле получает новое имя (с номером версии изменения, например field_name_v2) и никогда более не изменяется. Т.е. при следующей итерации миграции будет создано новое поле с именем field_name_v3, а field_name_v2 будет удалено.
2. Миграция должна выполняться до выкатки кода на сервер
3. Удобно, когда каждый шаг, это отдельный коммит/Merge/Pull Request, который попадает на ноды с неким промежутком времени.
p.s. возможно у Вас возникнут вопросы и я заблаговременно постараюсь на них ответить.
Q: почему миграция 2.1 не может быть выполнена в пункте 1.1
A: потому что в момент между 1.1 и 1.2. часть нод может добавить данные в базу данных только в старом формате. Подробнее:
1.1. код находится в директории tmp, запускается миграция, дожидаемся создания нового поля
1.2. последовательно выкатываем код на ноды, и в этот момент некоторые ноды все еще сохраняют данные только в поле field_name, они еще не знают, что нужно также сохранять данные в поле field_name_v2
Q: зачем в 2.2 код все еще пишет данные в поле field_name
A: выкатка кода на ноды выполняется последовательно, поэтому те ноды, на которые еще не пришел PR 2.2., все еще будут читать данные из поля field_name
Как видите, все просто, но если возникли вопросы - пишите в комментариях, удачки.