Восстановление не удаётся из-за отсутствующей функции chat_mention

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

Не знаю, что делать дальше.

                                                                                                                           [20/9694]
ERROR:  функция discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() не существует
EXCEPTION: psql завершился с ошибкой: ERROR:  функция discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() не существует
/var/www/discourse/lib/backup_restore/database_restorer.rb:92:in `restore_dump'                                
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in `restore'            
/var/www/discourse/lib/backup_restore/restorer.rb:51:in `run'
script/discourse:157:in `restore'   
/var/www/discourse/vendor/bundle/ruby/3.
4 лайка

Я уже сталкивался с этой ошибкой как на новой стандартной установке, так и на хостинге для бизнеса.

2 лайка

Я поднял внутренний сигнал «Бэтмена», мы займемся этим в ближайшие несколько дней.

4 лайка

Та же ошибка при попытке восстановления на новой установке, как и при переносе моего Discourse на другой сервер. Решения не найдено.

1 лайк

О, на самом деле я только что нашёл одно решение.

Мне повезло, что старый сервер всё ещё работает. Поэтому я пересобрал приложение лаунчера, чтобы привести старый сервер к точно такой же версии, как и новая установка. Затем я сделал ещё одну резервную копию через командную строку. При восстановлении этой резервной копии на новой установке всё прошло гладко. Попробуй этот способ. @pfaffman

2 лайка

Это могло бы решить мою проблему в одном месте. Спасибо!

Рад, что смог помочь!

1 лайк

Ой, я тоже с этим столкнулся. Пытаюсь восстановить данные из продакшн-системы в песочницу/разработку. Я также перепроверил, что все те же плагины установлены.Какой ещё плагин использует это? Сейчас проверю исходный код…

Хорошо, вот что я сделал:

  1. Убедился, что папка /var/discourse/shared пуста, или переместил её в новое место на случай, если потребуется восстановление.
  2. Инициализировал новый экземпляр Discourse с помощью команды ./launcher bootstrap .
  3. Попробовал выполнить восстановление снова, но получил ту же ошибку.
  4. Затем, сделав дамп рабочего экземпляра Discourse, я нашёл команду, которая создаёт эту функцию. Вот она:
CREATE FUNCTION discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
  BEGIN
    RAISE EXCEPTION 'Discourse: old_notification_id in chat_mention_notifications is readonly';
  END
$$;


ALTER FUNCTION discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() OWNER TO discourse;

После этого я снова попробовал выполнить восстановление, и всё прошло успешно!

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

УЛУЧШЕНИЕ: Было бы здорово иметь историю резервных копий и восстановлений. Возможно, она есть, но я не знаю, где её найти.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не сотрудник поддержки Discourse, поэтому не буду объяснять, как перейти в командную строку psql и выполнить указанные выше команды. : :slight_smile:

Проблема заключается в том, что миграция с более ранней временной меткой была добавлена в ветку tests-passed позже (@nbianca, FYI), и это не определяется метаданными версии в резервной копии. Я уже упоминал об этом здесь.

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

2 лайка

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

Или, если обе версии находятся за пределами ошибочного коммита, всё будет в порядке?

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

1 лайк

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

Похоже, проблема в том, что проверка версии в начале процесса восстановления не определяет, что в исходной базе данных была более новая схема, чем в целевой.

Да, я считаю, что это так.

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

1 лайк

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

1 лайк

Верно, это проблема, характерная для таких техник в целом. Это общая проблема для Ruby on Rails, а также для других реализаций ActiveRecord, таких как PHP Laravel. И, как вы отметили, это случается нечасто, и как только вы понимаете, что происходит, обходное решение при восстановлении найти несложно.

2 лайка

А иногда вы просто не захотите этого делать.

Похоже, если я просто обновлю два исходных сайта, с которыми работаю, у меня всё будет в порядке.

Ещё раз спасибо, Ричард!

1 лайк

Итак, в моем сценарии среда восстановления была новее, возможно, на пару версий, чем та, что была сохранена в резервной копии. Разве это не должно работать?

Сколько лет тому, где вы сделали резервную копию?

Это как раз то, что я собирался изучить! Секунду. Я хотел спросить, хранили ли мы журнал предыдущих резервных копий, или мы это делаем?

Поскольку восстановление выполняется в песочнице, я инициировал его снова. Это восстановление из продакшена в песочницу:

Вот данные из журнала восстановления:

[2024-10-21 19:49:59]   Текущая версия: 20241018031851
[2024-10-21 19:49:59]   Восстановленная версия: 20241011054348