Pull to refresh

Comments 17

UFO just landed and posted this here
Спасибо за комментарий!

И интересно сколько у вас миграций
на данный момент 230

Удивили ручными миграциями — у вас были факапы в проде? Я стараюсь отлавливать такие проблемы локально, а если никак уйти от неё нельзя — перехожу к миграциям батчами (в приложении или вне) без ломания обратной совместимости.
Я возможно не до конца понял вопрос, но постараюсь ответить. Под ручными миграциями (в комбинированном подходе) подразумевается вызов кода с миграцией из приложения (не подключение к БД и выполнение каких-либо скриптов руками). Т.е. это тот же код, что выполняет flyway, но не в момент прогона всех миграций, а в произвольное время, чтобы не замедлять релиз. В этом коде как раз часто бывают батчи. Поскольку схема данных в таких миграциях не изменяется, то, как правило, рисков нарушить обратную совместимость минимум.
Насчет факапов при релизе миграций – не было :-)

Это же решает и вопрос удаления колонки — сначала релизим код, который перестал её использовать, а затем уже удаляем. Пробовали? Чем не подошло?
Именно так и делаем. Я лишь имел ввиду, что несмотря на всю очевидность подобной миграции, состоящей из 2 последовательных шагов, и наличия соответствующих требований в инструкциях по написанию миграций, всегда есть риск человеческого фактора — «новичок/уставший разработчик/любой из нас» забыл и не подумал об этом, а на ревью не заметили. К счастью, пока такого не случалось — бывало, что «забывали», но на ревью отлавливали. Но все равно эту проверку хотелось бы автоматизировать.

А зачем столько миграций, первые несколько сотен разве нельзя смержить? Да и откат в случае проблем все равно будет вперёд идти.

К сожалению, flyway не имеет встроенного механизма для объединения миграций. Поскольку он проверяет набор выполненных миграций и миграций в коде, то чтобы заменить первые Х миграций на одну большую придется что-то сделать с таблицей schema_version (удалить старые Х миграций, добавить запись с правильной контрольной суммой для новой миграции). Для одного окружения, например только для production, это еще можно сделать, поскольку все БД на одной версии, но непонятно как быть с локальными средами разработчиков и тестовыми окружениями, где версии могут быть какими угодно.
В общем, мы уже думали над этой задачей, но пока приемлемого решения не нашли.
UFO just landed and posted this here
У большинства разработчиков в локальной БД есть какие-то тестовые данные, которые они используют (не говоря уже про отдельные тестовые окружения, где данных может быть много), и не хочется заставлять их тратить время на повторное создание этих данных. Хочется сохранить удобство текущего подхода и избежать лишних манипуляций — ты просто запускаешь сервер и база актуализируется автоматически.
Есть определенные идеи как сделать встроенную поддержу схлапывания миграций в flyway – надеюсь получится выделить время на доработку.
UFO just landed and posted this here
Я согласен с вами — тестовые данные нужны только для тестов и располагать их в общих миграциях будет неправильно. С другой стороны, если для тестов также хочется иметь версионность (т.е. для разных версий схемы данных разные тестовые наборы, а не только тесты для последней версии), то можно вести отдельную систему миграций. Примерно так:
Основные миграции:
V1_create_table1.sql
V2_alter_table1.sql
V3_create_table2.sql
Тестовые миграции:
V1_create_test_data_table1.sql
V2_create_test_data_table1.sql
V3_create_test_data_table2.sql
А при запуске тестов в зависимости от версии схемы данных накатывать на базу соответствующую миграцию с данными.

Не очень понимаю, когда это может быть нужно, но теоретически, наверное, имеет право на жизнь :-)

UFO just landed and posted this here

Есть одна жирная проблема с автоматическими миграциями: они должны быть линейно упорядочены. Это сильно усложняет жизнь, если несколько девелоперов пилят фичи в разных ветках. Приходится вручную контролировать порядок версий при сливе в master main, а каждый девелопер при апдейте из main должен ломать голову как применить предыдущие миграции на своей локальной базе. Есть ли какие-то рекомендации по этому поводу?

UFO just landed and posted this here
Да, вы правы, такая проблема есть. Мы решаем ее весьма костыльным (но работающим путем) — с помощью отдельного канала в слаке, где разработчики, создающие миграцию, «бронируют» очередную версию для себя. Там же они иногда «передоговариваются» о порядке и обмениваются версиями, чтобы не тормозить последующую миграцию в случае, когда один из pull request-ов завис на ревью. В целом у нас есть рекомендация разбивать реализацию функционала на несколько реквестов, 1й из которых — только sql-миграция без бизнес-логики, чтобы минимизировать время между «бронированием» версии и мержем миграции.
Также для того, чтобы гарантировать линейный порядок версий в мастере, мы используем плагин для bitbucket, который проверяет грубо говоря, что новый реквест имеет версию миграций +1 относительно последней миграции в мастере.

Стоить добавить, что поскольку не все миграции зависимы друг от друга, то иногда их можно выполнять в любом порядке (например, без разницы в каком порядке вы создадите 2 индекса) – для этого flyway имеет опцию outOfOrder. Но мы решили, что подобная двойственность (часть миграций упорядочена, часть нет) – еще одно место для потенциальных проблем (для упорядоченных миграций) и поэтому не используем ее и порядок всегда одинаков.

Мы на текущем проекте используем MySQL. У меня Windows, и поднятие чистого контейнера с docker hub занимает секунд 20, без pull. Миграций тоже около 100+, и, если не использовать tmpfs для data dir, поднятие контекста становится вечным. Ваш вариант (подготовить образ со схемой данных) тоже рассматривал, но сколкнулся с тем, что тесты все равно занимают много времени, если пишут на диск, а не в ОЗУ.
Сколько у вас тестов и как долго они выполняются? Не удалось ли вам с подготовкой образа как-то примонтировать tmpfs (может быть, копированием data dir через init.sh в образе)?
Если что, оставил свой путь в заметке: https://rocketscien.se/testcontainers

Сколько у вас тестов и как долго они выполняются?
Интеграционных тестов примерно 2 тысячи, выполняются около 5-7 минут.
Не удалось ли вам с подготовкой образа как-то примонтировать tmpfs (может быть, копированием data dir через init.sh в образе)?
Сконцентрировавшись на проблеме прогона миграций на запуске каждого тестового класса, мы почему-то даже не посмотрели в эту сторону, но выглядит перспективно, попробую — спасибо за идею и за вашу заметку!
Спасибо!
Кстати, для того, чтобы быстро откатывать вашу базу в начальное состояние вы можете посмотреть в сторону «тонкого клонирования» — быстрое создание копии файловой системы на основе ZFS. Есть даже более менее готовое решение — Database Lab. Сам я его на практике не пробовал, но вероятно, мы будем рассматривать его как один из вариантов для реализации т.н. «иммутабельных» тестовых сред (когда на каждый запуск набора e2e тестов создается новая база с подготовленными тестовыми данными).
Sign up to leave a comment.

Articles