Ошибка при миграции в S3

Я пытаюсь перенести загрузки на S3 на довольно загруженном сайте.
Всё идёт по плану, кроме момента, когда я запускаю rake uploads:migrate_to_s3, после чего получаю следующую ошибку:

Обновление URL-адресов в базе данных...
Удаление старых оптимизированных изображений...
Пометка всех постов с лайтбоксами для повторной обработки...
2023 поста помечены для повторной обработки
rake aborted!
FileStore::ToS3MigrationError: 1 из 9629 загрузок не перенесён на S3. Перенос на S3 не удался для БД 'default'.
/var/www/discourse/lib/file_store/to_s3_migration.rb:132:in `raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:79:in `migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:373:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:66:in `migrate'
/var/www/discourse/lib/tasks/uploads.rake:123:in `migrate_to_s3'
/var/www/discourse/lib/tasks/uploads.rake:102:in `block in migrate_to_s3_all_sites'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-4.0.0/lib/rails_multisite/connection_management.rb:80:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-4.0.0/lib/rails_multisite/connection_management.rb:90:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:100:in `migrate_to_s3_all_sites'
/var/www/discourse/lib/tasks/uploads.rake:96:in `block in <main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Задачи: TOP => uploads:migrate_to_s3
(Полный трассировочный вывод можно получить, запустив задачу с флагом --trace)

Особенно привлекла внимание эта строка: FileStore::ToS3MigrationError: 1 из 9629 загрузок не перенесён на S3. Перенос на S3 не удался для БД 'default'.

Предполагаю, что это означает наличие одного проблемного файла, из-за которого вся задача rake завершается неудачей? Есть ли способ выяснить, какой именно файл вызывает проблему, и, возможно, просто удалить его, чтобы остальная часть задачи завершилась успешно?

Некоторое обновление:
Сайт, похоже, загружается нормально, и, насколько я вижу, загруженные изображения обслуживаются через CDN.
Локальная копия всех загрузок по-прежнему существует на сервере. Я предполагаю, что это связано с тем, что миграция помечена как неудачная.
Вот вывод команды rake uploads:s3_migration_status, если это может быть полезно:

# rake uploads:s3_migration_status
1 из 9630 загрузок не перенесено в S3. Миграция в S3 не удалась для базы данных 'default'.
19 сообщений не переназначены на новый URL загрузки S3. Миграция в S3 не удалась для базы данных 'default'.
Нет сообщений, требующих повторной обработки.
Сайт не готов к миграции.

Вы можете найти ссылку на файл, который не удалось загрузить, в разделе Администрирование > Журналы > Журнал ошибок.

Если это не поможет, я думаю, что поиск в базе данных записей с полем cooked, содержащим yourdomain/uploads/, позволит вам получить список из 19 записей, упомянутых в статусе миграции. В худшем случае вы сможете затем вручную просмотреть их и сравнить загруженные файлы с тем, что находится в S3.

Что-то вроде:

rails c
Post.where("cooked like '%discourse.example.com/uploads/%'")

Привет, @Simon_Manning

Я попробовал ваши рекомендации. К сожалению, в журналах ошибок ничего релевантного найти не удалось. Я вижу запись вида
Failed to optimize image: unknown reason, но она не дает никакой дополнительной информации, кроме того, что в ней написано.

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

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

Возможно, будет проще извлечь все имена файлов из результата запроса (например, f8a2d9381889b8693db2777acac566bd7b134fa5.png) и поискать их в S3. Теоретически должен отсутствовать ровно один файл. Игнорируйте производные файлы, ищите только те, в пути которых есть /originals/.

Это немного утомительно, но не должно занять много времени, если этот запрос выбрал только эти 19 постов.

Итак, я нашел виновника. Как мне действовать?

То, что кажется мне логичным, может оказаться не лучшим выходом.
Вот варианты, которые я вижу:

  1. Удалить ссылку на файл из проблемного сообщения.
  2. Удалить файл с сервера.
  3. Перенаправить ссылку на файл на что-то общее.

Или, возможно, я мыслю совершенно неверно?

Если очевидного решения для успешной загрузки нет, то лучше выбрать вариант 1 или 3. Вариант 2, скорее всего, стоит доверить Discourse — в частности, задаче по очистке «осиротевших» загрузок. Интервал её выполнения контролируется настройкой clean orphan uploads grace period hours.

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

Ещё один вариант, который можно попробовать после удаления файла, завершения миграции (и скачивания проблемного файла), — снова отредактировать пост, чтобы вернуть файл. Было бы интересно узнать, не удаётся ли загрузить его в S3 вообще или только в ходе задачи миграции.

У меня та же ошибка, на 64-м посте. Невозможно найти их среди 80 тысяч файлов…

Что будет, если я удалю локальные файлы (большинство из них уже перенесены)?

Я подтверждаю, что файлы перемещены, но у меня возникла та же ошибка.

Есть какие-либо предложения? Загрузка на S3 работает нормально, но задача: миграция на S3 завершается неудачей.

Если вы готовы потерять эти 64 файла, то вот что я сделал, когда эта же задача Rake постоянно терпела неудачу: я отредактировал её, чтобы она выдавала ошибку только при наличии 100 ошибок вместо одной.

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

Сначала попробуйте запустить команду: SKIP_FAILED=1 rake uploads:migrate_to_s3.

Если это не поможет, отредактируйте эту строку и попробуйте снова:

Попробовал выполнить команду SKIP_FAILED=100 rake uploads:migrate_to_s3

=> 0 файлов

  • Список файлов S3
    … .. => 81070 файлов
  • Синхронизация файлов с S3

Обновление URL-адресов в базе данных…
Удаление старых оптимизированных изображений…
Пометка всех сообщений, содержащих лайтбоксы, для повторной сборки…
54453 сообщения помечены для повторной сборки
53 сообщения не были сопоставлены с новым URL-адресом загрузки S3. Миграция S3 не удалась для базы данных ‘default’.

Я не понял, как поместить изменённый файл в свой скрипт Discourse.

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

Попробовал с этой командой… тот же результат.

Ах, как жаль. Есть ещё предложение от @Falco — отредактировать задачу rake, но, к сожалению, я не знаю, как это сделать, и не могу найти никаких инструкций при поиске. :slightly_smiling_face:

Надеюсь, кто-нибудь другой сможет помочь? :crossed_fingers:

Мне удалось создать myscript.rb в папке /shared, но я не могу его запустить.

Есть ещё какие-нибудь предложения? @vulkanino, я заметил, что у вас была похожая проблема