После обновления до версии 2.7beta7 произошла имплозия

Всем привет,

Мы уже несколько лет используем самохостинг Discourse по адресу https://discourse.bokeh.org. В целом система работала безотказно и практически не требовала обслуживания. В частности, обновления обычно проходили абсолютно незаметно и завершались без каких-либо проблем.

Однако сегодня после обновления до версии 2.7beta7 (которое, казалось, прошло без сбоев) наш сайт полностью перестал работать. Некоторое время он функционировал с ошибками рендеринга страниц и ошибками в консоли JS, но после попытки отката интерфейс стал полностью неработоспособным. Зайдя на сервер (droplet), я также безрезультатно попробовал следующее:

Пересборка

./launcher rebuild app

Это несколько раз завершалось неудачей разными способами.

Discourse Doctor

./discourse-doctor

Восстановление

./launcher enter app
discourse restore <файл резервной копии>

Это также не сработало.

Очистка

Я также попробовал выполнить “очистку” (wipe), а затем восстановить:

./launcher stop app
./launcher destroy app
rm -r /var/discourse/shared/standalone/

После этого мне хотя бы удалось успешно выполнить пересборку, что привело к состоянию “чистой установки”, например, с сообщением: “Congratulations, you installed Discourse!”.

Теперь я снова попытался запустить discourse restore, но это снова не удалось.

EXCEPTION: 1 post не переотображен на новый URL загрузки S3. Миграция S3 не удалась для базы данных 'default'. /var/www/discourse/lib/file_store/to_s3_migration.rb:131:in `raise_or_log' /var/www/discourse/lib/file_store/to_s3_migration.rb:86:in `migration_successful?' /var/www/discourse/lib/file_store/to_s3_migration.rb:357:in `migrate_to_s3' /var/www/discourse/lib/file_store/to_s3_migration.rb:65:in `migrate' /var/www/discourse/lib/file_store/s3_store.rb:240:in `copy_from' /var/www/discourse/lib/backup_restore/uploads_restorer.rb:62:in `restore_uploads' /var/www/discourse/lib/backup_restore/uploads_restorer.rb:44:in `restore' /var/www/discourse/lib/backup_restore/restorer.rb:62:in `run' script/discourse:145:in `restore' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/base.rb:485:in `start' script/discourse:286:in `' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `load' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `kernel_load' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:28:in `run' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:494:in `exec' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:30:in `dispatch' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:24:in `start' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:49:in `block in ' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/friendly_errors.rb:130:in `with_friendly_errors' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:37:in `' /usr/local/bin/bundle:23:in `load' /usr/local/bin/bundle:23:in `' Попытка отката... Выполняется откат... Очистка временных файлов... Удаление функций из схемы discourse_functions... Удаление временной директории '/var/www/discourse/tmp/restores/default/2021-04-23-235404'... Отметка восстановления как завершенного... Уведомление 'system' об окончании восстановления... Завершено! [FAILED]

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

Мне очень нужна любая помощь или советы. У нас есть ежедневные резервные копии за последнюю неделю (более старые доступны в Glacier, если потребуется). Несколько дней назад мы удалили неиспользуемую категорию — не могло ли это стать причиной проблем? Я попробую восстановить из более старой резервной копии, но буду благодарен за любые рекомендации по надежному процессу восстановления.

Старая резервная копия не помогла. Во время восстановления всё выглядело «вроде бы нормально»

До самого конца, а затем сразу происходит следующее:

Кстати, разве в резервной копии нет постов, которые изначально были импортированы из рассылки, но уже много лет находятся на сайте Discourse?? У нас было 24 тысячи постов, а не 5 тысяч до этого.

Можно ли пересобрать приложение для другой версии Discourse, например для 2.7beta6?

Впрочем, я полагаю, что проблема вызвана буквально одним-единственным сообщением.

EXCEPTION: 1 posts are not remapped to new S3 upload URL. S3 migration failed for db ‘default’.

Возможно ли найти это сообщение и просто удалить его?

У вас есть изображения на S3?

@pfaffman Да, у нас есть изображения на S3

Хм. Возможно, проблема лишь в одном повреждённом сообщении? Думаю, вам нужно будет восстановить базу данных, исправить её, а затем заново создать файл резервной копии с обновлённой базой. Но точно сказать сложно.

Есть ли где-то инструкции, как это сделать? Как я могу определить, какой именно пост сломан?

Редакция: Или, может быть, есть кто-то, кто обладает соответствующей экспертизой и может быть нанят для оказания услуг?

Есть ли у вас свежая резервная копия или снимок (snapshot) Droplet, которые вы можете восстановить?

У вас есть свежая резервная копия или снимок droplet, которые можно восстановить?

К сожалению, нет. Резервные копии DO делаются только раз в неделю, а я настроил ежедневные резервные копии Discourse в S3, храня свежие копии за неделю и архив за год в Glacier. Учитывая мой предыдущий положительный опыт с множеством обновлений Discourse, я думал, что этого будет достаточно и даже лучше (к тому же я уже успешно проводил тестовые восстановления ранее).

Допустим, version: 94301854938a0b36dd64666fb7a7c8406544a781 — это коммит непосредственно перед повышением бета-версии.

Ну, на самом деле это обновление. В приступе отчаяния я просто принудительно прервал скрипт восстановления на этапе

Синхронизация файлов с S3

до того, как он сообщил о 1 ошибочном посте и начал откат.

Сайт фактически вернулся в рабочее состояние и стал доступен в безопасном режиме. Я отключил компонент темы «КОПИРОВАТЬ/ВСТАВИТЬ» для блоков кода, который, как выяснилось, теперь крайне несовместим с последней бета-версией. После этого сайт, похоже, действительно в основном работает нормально, даже без безопасного режима. Однако:

  • Есть ли какие-либо рекомендуемые действия, чтобы убедиться, что всё максимально «очищено»? Например, повторная загрузка ресурсов в S3 и «перепечка»? Где найти лучшие, самые актуальные инструкции для этого?

РЕДАКТИРОВАНИЕ: насколько я могу судить, всё вернулось в норму. Изображения в старых постах корректно загружаются из S3/CDN. Тогда мой вопрос: если мы загружаем изображения в S3, должна ли эта опция быть снята?

Включать загрузки в запланированные резервные копии. Отключение этого параметра приведёт к резервному копированию только базы данных.

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

В прошлый раз, когда я переезжал на другого хостинг-провайдера, у меня тоже возникли проблемы с S3 при восстановлении. Поэтому я уточнил этот момент, и ответ был утвердительным. Если вы храните изображения в S3, то необходимо делать резервную копию без загрузок. Только базу данных. Но я не знаю, подходит ли это решение в вашем случае. Если решите попробовать, обязательно создайте снимок состояния перед этим.

Подробнее можно прочитать здесь: Restore a backup from the command line - #28

Я только что попробовал, и всё сработало отлично, без каких-либо проблем. :slightly_smiling_face:

Я могу помочь. В понедельник или раньше — за опасную работу.

Вы можете Contact Us - Literate Computing наш S3, email-адрес указан в нижней части страницы.

@pfaffman Спасибо! Сайт, похоже, теперь работает абсолютно нормально, но я не откажусь от вашего быстрого взгляда / проверки на sanity, если у вас найдётся время. В любом случае я сохранил вашу коммерческую контактную информацию на случай любых будущих чрезвычайных ситуаций. :slight_smile:

Вот ретроспективный отчёт, на случай если он будет полезен кому-то ещё.


РЕЗЮМЕ

После (успешного) обновления несовместимый неофициальный плагин компонента темы привёл к поломке интерфейса сайта. Об этом не было известно в тот момент, поэтому был инициирован процесс восстановления из резервной копии, но он столкнулся с проблемами из-за неидеальной конфигурации.

ДЕТАЛИ

  1. Было инициировано обновление до версии 2.7beta7, которое успешно завершилось.

  2. Однако после обновления интерфейс сайта был серьёзно нарушен: содержимое постов полностью отсутствовало, верхняя навигация (включая разделы пользователя / входа) полностью отсутствовала, консоль JS сообщала об ошибках.

    1. Причиной этого оказался несовместимый сторонний компонент темы для копирования и вставки блоков кода, но об этом не было известно в тот момент.

    2. Также не было известно о возможности входа в безопасный режим. Если бы это было известно, остальные проблемы можно было бы избежать.

  3. Был получен доступ к \admin через прямой переход, и была предпринята попытка отката. Это немедленно вывело пользователя из системы, и не было видно способа снова войти при сломанном интерфейсе.

  4. Вошел в Digital Ocean Droplet, чтобы инициировать ручное восстановление с помощью последнего архива резервной копии из S3.

  5. Многие попытки восстановления завершались неудачей на последнем этапе, после загрузки ресурсов из S3, из-за ошибки в одном посте.

    1. Это, очевидно, связано с тем, что восстановления, пытающиеся повторно загрузить ресурсы в S3, могут быть нестабильными (несколько сообщений об этом на Meta).
    2. Однако не было необходимости делать резервную копию загруженных ресурсов, поскольку они уже хранятся в S3!
  6. Во время одной из многочисленных попыток восстановления сайт также был полностью очищен, чтобы попробовать начать с «чистого листа», поэтому откаты после неудачных восстановлений теперь возвращали к пустому сайту.

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

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

  9. Все неофициальные плагины и темы были удалены (включая компонент «копировать-вставить»), после чего сайт заработал нормально.

  10. Подтверждено, что ранее загруженные изображения продолжают загружаться из CDN S3.

Я подозреваю, что финальная загрузка и «пересборка» не были нужны, так как ресурсы уже находились в S3, и посты не требовали обновления для использования новых URL.

Я не уверен, какие шаги восстановления, если таковые были, были пропущены после прерывания скрипта, но пока никто не столкнулся с проблемами на сайте в его текущем состоянии.

УРОКИ / ДЕЙСТВИЯ

  • Начинать с безопасного режима для диагностики проблем в будущем.
  • Отключить настройку включения загрузок в резервные копии (предложу Discourse предупреждать о такой ситуации).
  • Удалить все неофициальные плагины и компоненты тем.
  • Предложить включить новую встроенную функцию копирования блоков кода.
  • Включить еженедельные резервные копии образов Digital Ocean как запасной вариант для восстановления.

Компонент темы или плагин? Не могли бы вы сообщить об этом автору?

@merefield Похоже, это уже известно, и именно так я узнал о возможности

https://meta.discourse.org/t/copy-option-for-code-blocks-in-discourse/60961

Если бы мне пришлось дать одну рекомендацию касательно процесса восстановления, я бы предложил добавить несколько опций для повышения его устойчивости. Например, если единственное, что мешает успешному восстановлению, — это один проблемный пост, я бы без колебаний нажал клавишу Y, если бы меня спросили: «Удалить проблемный пост?»

Это появится в одной из следующих бета-версий 2.8. К сожалению, для предстоящего релиза 2.7 это ещё не готово.

Извините, что я не увидел ваш призыв о помощи раньше. Вот совет для всех, кто сталкивается с проблемами восстановления из-за загрузок, хранящихся на S3: извлеките файл dump.sql.gz из резервной копии и переименуйте его. Например, если исходная резервная копия называлась discourse-2020-10-09-133921-v20201007124955.tar.gz, то итоговый файл должен называться discourse-2020-10-09-133921-v20201007124955.sql.gz. Восстановление этого файла должно пройти успешно.