⚡️Expand and contract (zero downtime migrations)
Когда вам нужно мигрировать приложение на новую схему данных, у вас есть два пути
Первый вариант — за один релиз задеплоить новый код и миграцию схемы и самих данных. Если у вас данных не очень много и/или вы можете позволить себе даунтайм, это прекрасно
Второй вариант — страдания
Для таких миграций без даунтайма есть весьма понятный подход, называемый expand and contract
Посмотрим на примере:
Есть — одна колонка в бд содержащая и имя, и фамилию пользака user = "Walter Black"
Хочется — две отдельные колонки name = "Walter", surname = "Black"
1. Добавляем новые нуллабельные колонки
Отдельный релиз — накатываем миграцию схемы данных
2. Начинаем писать и в старую, и в новую схему
Отдельный релиз — при апдейтах/инсертах user = "Walter Black" также проставляем name = "Walter", surname = "Black"
3. Мигрируем старые данные
Отдельный релиз/запуск скрипта — пишем скрипт, который в старых записях проставит значения новым колонкам. После завершения миграции хорошо бы чекнуть, что данные в двух схемах действительно эквивалиентны друг другу. После этого этапа у нас есть все данные одновременно в двух схемах
4. Начинаем читать из новой схемы
Отдельный релиз — в коде приложения начинаем читать данные не из старой колонки, а из новых
5. Выпиливаем запись в старую схему
Отдельный релиз — перестаем писать в старую колонку
6. Выпиливаем старую схему
Отдельный релиз — миграция, которая дропает старую колонку user
---
Итого: за 5-6 релизов получаем безопасную миграцию схемы данных. Важно, что здесь при неудачном релизе мы всегда можем безопасно его откатить. Конечно, такие жесткие гарантии требуются не всегда, и зачастую происходит слияние каких-то шагов, если допустим короткий даунтайм
Шаги в виде картинок в комментах
Когда вам нужно мигрировать приложение на новую схему данных, у вас есть два пути
Первый вариант — за один релиз задеплоить новый код и миграцию схемы и самих данных. Если у вас данных не очень много и/или вы можете позволить себе даунтайм, это прекрасно
Второй вариант — страдания
Для таких миграций без даунтайма есть весьма понятный подход, называемый expand and contract
Посмотрим на примере:
Есть — одна колонка в бд содержащая и имя, и фамилию пользака user = "Walter Black"
Хочется — две отдельные колонки name = "Walter", surname = "Black"
1. Добавляем новые нуллабельные колонки
Отдельный релиз — накатываем миграцию схемы данных
2. Начинаем писать и в старую, и в новую схему
Отдельный релиз — при апдейтах/инсертах user = "Walter Black" также проставляем name = "Walter", surname = "Black"
3. Мигрируем старые данные
Отдельный релиз/запуск скрипта — пишем скрипт, который в старых записях проставит значения новым колонкам. После завершения миграции хорошо бы чекнуть, что данные в двух схемах действительно эквивалиентны друг другу. После этого этапа у нас есть все данные одновременно в двух схемах
4. Начинаем читать из новой схемы
Отдельный релиз — в коде приложения начинаем читать данные не из старой колонки, а из новых
5. Выпиливаем запись в старую схему
Отдельный релиз — перестаем писать в старую колонку
6. Выпиливаем старую схему
Отдельный релиз — миграция, которая дропает старую колонку user
---
Итого: за 5-6 релизов получаем безопасную миграцию схемы данных. Важно, что здесь при неудачном релизе мы всегда можем безопасно его откатить. Конечно, такие жесткие гарантии требуются не всегда, и зачастую происходит слияние каких-то шагов, если допустим короткий даунтайм
Шаги в виде картинок в комментах