Multisite восстанавливает загрузки в 'default' вместо реального имени базы данных

В последней бета-версии Discourse с установкой через Docker и поддержкой нескольких сайтов.

Пытаюсь восстановить резервную копию из исходной базы данных REDACTED в текущую базу данных db8015. Файлы загрузок оказываются в default, как в файловой системе, так и в базе данных.

Это происходит как при запуске восстановления через графический интерфейс, так и при выполнении восстановления из командной строки с помощью команды RAILS_DB=db8015 RAILS_ENV=production script/discourse restore.

В процессе восстановления RailsMultisite::ConnectionManagement.current_db меняется с правильной базы данных на default. Мне удалось отследить это изменение до строки [Rake::Task['db:_dump'].invoke в файле db.rake](https://github.com/discourse/discourse/blame/master/lib/tasks/db.rake#L59).

До этой строки RailsMultisite::ConnectionManagement.current_db имеет правильное значение (db8015), а после неё — default.

Похоже, что это исправление каким-то образом сломало работу в production-окружении, @sam?

Логи:

[НАЧАЛО]
'DHSupport' запустил восстановление!
Помечаем восстановление как запущенное...
Проверяем существование директории /var/www/discourse/tmp/restores/db8015/2019-10-11-104940...
Копируем архив во временную директорию...
Распаковываем архив, это может занять время...
Файл метаданных для извлечения отсутствует.
Проверяем метаданные...
  Текущая версия: 20191007140446
  Восстанавливаемая версия: 20190908234054
Извлекаем дамп базы данных...
Создаем отсутствующие функции в схеме discourse_functions
Невозможно восстановить в другую схему, восстанавливаем на месте
Включаем режим только для чтения...
Приостанавливаем sidekiq...

[удалил много нерелевантного]

Очищаем кэш тем
Извлекаем загрузки...
Переназначаем загрузки...
Переназначаем 'uploads/REDACTED' в 'uploads/default'
Оптимизируем иконки сайта...
Сообщения будут пересобраны фоновой задачей в sidekiq. Вы увидите отсутствующие изображения до завершения этого процесса.
Вы можете ускорить процесс, вручную запустив "rake posts:rebake_uncooked_posts"
Выполняем after_restore_hook...
Очищаем временные данные...
Удаляем функцию из схемы discourse_functions
Удаляем временную директорию '/var/www/discourse/tmp/restores/db8015/2019-10-11-104940'...
Возобновляем работу sidekiq...
Помечаем восстановление как завершенное...

Это всё ещё проблема, @sam?

Для уточнения: воспроизведение выглядит так:

  • Создать мультисайт в контейнере Docker

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

  • Восстановить её в новом контейнере Docker

  • Файлы загрузок оказываются не в том месте

@kris.kotlarek, сможешь ли ты воспроизвести это локально и попытаться исправить?

Я подозреваю, что в будущем мы столкнёмся с этой проблемой.

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

  • Создайте форум в контейнере Docker
  • Создайте резервную копию
  • Восстановите её в новом мульти-сайтовом контейнере Docker
  • Загрузки находятся не в том месте

Я потратил некоторое время на этот баг и хотел сообщить вам о своих выводах. По сути, я подтвердил всё, что вы уже сказали: процесс восстановления выглядит так:

migrate_database
reconnect_database
...
extract_uploads

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

Поэтому этот код некорректен:

def extract_uploads
  ...
  current_db_name = 
  RailsMultisite::ConnectionManagement.current_db # default
  optimized_images_exist = File.exist?(File.join(tmp_uploads_path, 'optimized'))

Хакерское решение — использовать здесь @current_db, который всё ещё содержит правильное имя, вместо RailsMultisite::ConnectionManagement.current_db, но это не решает реальную проблему: почему reconnect_database работает некорректно.

Мне нужно копнуть глубже, чтобы найти причину.

Вы точно уверены, что это происходит после задачи миграции?

Этот код

  migrate_database
  puts "После миграции, до переподключения #{RailsMultisite::ConnectionManagement.current_db}"
  reconnect_database

выводит следующее:

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

Но когда вы закомментировали строку

Rake::Task['db:_dump'].invoke

в lib/tasks/db.rake

Вывод стал таким:

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

Вы правы. Я удалил Rake::Task["db:migrate"].invoke из restorer.rb, и в результате база данных корректно восстановилась на протяжении всего процесса. Вы на шаг впереди меня; мой план сейчас — зайти в задачу миграции и посмотреть, какой именно шаг прерывает процесс. Спасибо, что указали на _dump, я сразу зайду туда, чтобы разобраться, что происходит внутри.

Я потратил некоторое время на расследование этого, но в конце концов нашёл решение :slight_smile:

Спасибо!

После ещё раз обдумывания, что вообще означает запуск db:dump для базы данных, которая не является основной?

Разве не должно оно просто пропускать команду db:dump, если база данных не является базовой?

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