Отслеживание и устранение причины дрейфа схемы

Итак, пытаюсь перенести сайт, восстанавливая резервную копию из существующего развертывания. Восстановление завершается ошибкой из-за несоответствия схемы (источник новее, чем цель).

Теперь, просматривая эндпоинт admin/plugins для обоих развертываний, вижу, что перечисленные плагины совпадают по статусу и версии, что немного сбивает с толку. Я также попробовал вернуть все темы и компоненты на всякий случай, но это тоже не помогло. Оба сайта работают на версии приложения 3.1.3, так что это, похоже, не корневая причина в данном случае.

Предполагаю, что на сайте был установлен плагин, затем экземпляр был пере развернут, а база данных сохранена без этого плагина, но это лишь предположение. Существует ли детерминированный способ, исходя из экземпляра или базы данных, определить, что вызвало дрейф схемы? И есть ли способ «понизить версию» (down rev), или единственный метод — заставить целевой сайт соответствовать или быть надмножеством?

Возможно, старая версия была бета-версией или тесты прошли, но она нестабильна, поэтому последняя стабильная версия на самом деле старше?

Стоит проверить, совпадают ли номера коммитов (если это возможно).

Резервная копия относится к базе данных, поэтому, думаю, наличие плагинов не имеет значения: они просто добавят данные плагинов, но не будут их использовать…

Я в это не очень верю, но раз это окружение разработки, то, полагаю, возможно всё что угодно.

Есть ли что-то известное вам в таблице schema_migrations (или в клонированном коде контейнера), что я мог бы проверить вручную и сопоставить версию схемы с соответствующим изменением?

Переименование файла позволяет загружать данные через UI, но я использовал merger, который блокируется на основе max(schema_migrations), и я действительно стараюсь избегать излишнего хака.

Часть этих действий опережает любые операционные задачи, где могут проявиться несоответствия версий миграций. Лучше понять, как отслеживать версию миграции обратно к изменениям, чтобы в следующий раз, когда это произойдёт, я мог составить runbook по устранению расхождений.

rails db:version

в командной строке в директории Discourse… но если вы не восстанавливали базу данных, это может не помочь…

или через psql:

SELECT * FROM schema_migrations ORDER BY version DESC LIMIT 1;

Затем вы можете найти эту запись на GitHub, чтобы сопоставить её с коммитом…

например: https://github.com/search?q=repo%3Adiscourse%2Fdiscourse+20231222030024&type=code

Откройте файл миграции и обратите внимание на коммит, в котором он был добавлен, чтобы подтвердить дату и т. д.

NB: это не обязательно совпадает с коммитом кода, очевидно! Он может быть более старым :slight_smile: (который можно получить командой git log -1)

Да, я вижу максимальную версию schema_migration (даже просто глядя на имя файла резервной копии), но проверил таблицу — там только дата. Никаких указаний, откуда она взялась.

Например, «хорошее» значение — 20230823100627, а на сайте — 20231022224833. Я даже не могу найти файлы за «20231022» в папке post_migrate (или где-либо ещё в репозитории).

Я уверен, что ответ лежит прямо на поверхности. Да, я перебираю прошлые изменения и письма, пытаясь понять, можно ли сопоставить какое-то действие после августа, когда могла незаметно проникнуть ошибочная версия.

Подождите, вы пытаетесь восстановить экземпляр разработки в производственную базу данных или наоборот?

Я никогда не пробовал этого делать, только из производства в производство (где имена баз данных и другая конфигурация согласованы).

В данном случае речь идет об экземпляре Dev, подключенном к недавно созданному экземпляру “Merge”, который я затем использую с помощью утилиты merger для импорта другого экземпляра Dev в рамках тестирования усилий по консолидации экземпляров, которые мы сейчас реализуем. Синхронизация ревизии миграции схемы является обязательным условием (что неудивительно). В данном случае целевая среда работает на версии 1022, а исходная — на версии 0823. Во всех доступных у меня версиях 3.1.3 используется версия 0823, поэтому меня беспокоит, откуда взялась версия 1022, и именно это я пытаюсь выяснить, но не могу найти никаких следов.

Окей, ваш рабочий процесс очень… необычен!

В идеале вам не следует хранить какие-либо данные в среде разработки и вы должны иметь возможность просто сбросить базу данных и заново выполнить миграции.

Чтобы объединить две расходящиеся среды разработки, обычно нужно слить ветки кода, включая миграции, а затем создать новый экземпляр с нуля.

Отчасти поэтому есть удобная задача Rake для предварительного заполнения тестовыми данными, чтобы было с чем работать: rake dev:populate

У нас как раз есть база данных со всеми идентификаторами миграций для более чем 400 плагинов, что позволяет нам легко сопоставлять их с плагинами. Этот идентификатор взят из discourse-automation.

Хех, да, все сельскохозяйственные животные сбежали из сарая уже довольно давно, поэтому я пытаюсь загнать всех обратно в загон. Или хотя бы понять, вообще ли это возможно.

И мы нашли недостающую часть, исследуя файловую систему экземпляра.

Люди искали в модуле Automate, но в других окружениях он никогда не был активирован, поэтому он просто отображался в списке плагинов, а изменений схемы не производилось. Это далеко не идеально, но подсказка для меня в этой работе — проверять репозитории всех установленных плагинов, даже если они отключены, ведь возможно, они когда-то были включены.

Мы проводим переразвертывание, удаляя некоторые из этих R&D-плагинов, а также будем уделять гораздо больше внимания записям плагинов в базе данных и вести там более тщательный учёт.

Кстати, поиск по GitHub — ваш друг в этом вопросе

Да, мы тоже наконец разобрались, посмотрев на сам рантайм экземпляра, но это далеко от идеала. Урок усвоен для операционного runbook, если он нам понадобится. Я просто не проверил репозиторий автоматизации в организации, так как он, казалось, был отключен, и не было записей о том, что кто-то его использует. Это была моя ошибочная предпосылка.

@RGJ, есть ли шанс, что эта база данных доступна где-то публично? Использование файловой системы экземпляра «работает», но становится более запутанным, чем мне бы хотелось.

Вы имеете в виду, что люди не запушили свои коммиты?

Что вы пытаетесь спасти?

Да, я искал внутри самого репозитория Discourse, а не по всему миру, так как не был уверен, что результат вообще появится. Поиск без указания области поиска слишком затратен, но я не выходил за пределы организации, чтобы проверить, есть ли результаты по официальным усилиям проекта Discourse.

У нас есть 3 или 4 экземпляра Discourse, которые были запущены независимыми командами для решения общей бизнес-задачи, и мы рассматриваем возможность объединения всех в один экземпляр, не теряя при этом их предыдущую работу.

Не могу поверить, что считается хорошей практикой полагаться на сохранение данных в среде разработки.

Если данные важны, эта работа, вероятно, должна выполняться в продакшене в более контролируемых условиях.

Я не знаю всей сути того, что вы пытаетесь сделать, но, будучи принципиальным, решения почти наверняка должны быть плагинами, которые можно развернуть где угодно, и они даже не должны полностью зависеть от конкретной версии Discourse, а также не должны зависеть от того, предзаполнены ли какие-либо данные за пределами инициализации собственных тестовых наборов.

Да, всё верно :100:

В данном случае мы оцениваем возможность выполнения этих операций слияния для продакшн-инстансов, используя несколько инстансов разработки. Если нам удастся сделать инструкцию (runbook) надёжной, то все данные и инстансы будут уровня продакшн, хотя до сих пор они поддерживались независимыми командами. Поэтому сейчас я работаю над тем, чтобы определить препятствия для успешного слияния. Версия схемы, очевидно, является ключевым фактором, и как приложение, так и плагины могут и будут влиять на «возможность слияния». К счастью, на продакшн-инстансах уже используется версия 0823, поэтому эта конкретная проблема не возникнет при запуске в продакшене, но понимание того, как анализировать расхождения в схеме, было необходимо и действительно поможет нашей документации по операциям.

Ага, понятно, так что вы прототипируете слияние производственных баз данных, интересно.

Но что именно вы пытаетесь слить?

Вы же знаете, что перенос тем (и их пользователей!) между экземплярами официально поддерживается?:

Да, это тысячи существующих тем и связанного контента, поэтому отдельные случаи немного запутаны.

Merge two Discourse sites into one, где используется другой скрипт, но та же основная идея.

Также я обнаружил ещё один нюанс, касающийся схем. Мы удалили плагин Automation из развёртывания и снова его развернули. Затем я заметил, что версия в таблице schema_migration, похоже, вернулась к 0823 как последней. Я подумал, что могу обойтись без установки плагина Automation в экземпляр, который я объединяю. Однако при следующем запуске импорта возникла ошибка PG::UndefinedTable: ERROR: relation "discourse_automation_automations" does not exist. Получается, что, хотя версия миграций откатилась, связанные с ней изменения схемы в самой базе данных всё ещё остались.