Хорошо, это должно было случиться — слишком долго всё шло слишком хорошо. Годы работы в режиме «автопилота»: система обновлялась автоматически, а я обновлял Discourse каждые несколько недель. В полночь прошлой ночью Amazon показал, что система не отвечает: Discourse был недоступен, а загрузка процессора достигла 100%, пока не закончились ресурсы CPU на AWS. Не удалось войти в систему; единственный раз, когда после нескольких перезагрузок мне удалось на мгновение получить доступ, я увидел в htop процесс, потребляющий много CPU:
snap lxd activate
Если кто-то сталкивался с этим и может объяснить, почему это могло произойти само по себе, буду очень признателен для будущих ссылок.
Переходя к насущной проблеме: я пересобрал новый сервер на AWS под Ubuntu 20 LTS. Настройка Discourse оказалась чрезвычайно простой. У меня была копия файла app.yml, которую я использовал для воссоздания форума Discourse. Старый сервер использовал S3 как для резервных копий, так и для контента (изображения и т. д.).
После создания сервера я загрузил последнюю резервную копию Discourse из S3, вручную загрузил её на сервер Discourse и нажал кнопку «Восстановить». Через несколько минут я получил эту ошибку.
[2022-06-09 09:01:56] ALTER TABLE
[2022-06-09 09:01:56] ALTER TABLE
[2022-06-09 09:01:56] Миграция базы данных...
[2022-06-09 09:02:11] == 20220308201942 CreateUploadReferences: миграция ===========================
-- create_table(:upload_references, {})
-> 0.0486s
-- add_index(:upload_references, [:upload_id, :target_type, :target_id], {:unique=>true, :name=>"index_upload_references_on_upload_and_target"})
-> 0.0030s
== 20220308201942 CreateUploadReferences: миграция завершена (0.0580s) ==================
== 20220309132719 CopyPostUploadsToUploadReferences: миграция ================
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT post_uploads.upload_id, 'Post', post_uploads.post_id, uploads.created_at, uploads.updated_at\nFROM post_uploads\nJOIN uploads ON uploads.id = post_uploads.upload_id\nON CONFLICT DO NOTHING\n")
-> 0.0595s
== 20220309132719 CopyPostUploadsToUploadReferences: миграция завершена (0.0602s) =======
== 20220309132720 CopyPostUploadsToUploadReferencesForSync: миграция =========
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT upload_id, 'Post', post_id, NOW(), NOW()\nFROM post_uploads\nON CONFLICT DO NOTHING\n")
-> 0.0076s
== 20220309132720 CopyPostUploadsToUploadReferencesForSync: миграция завершена (0.0080s)
== 20220330160747 CopySiteSettingsUploadsToUploadReferences: миграция ========
-- execute("WITH site_settings_uploads AS (\n SELECT id, unnest(string_to_array(value, '|'))::integer upload_id\n FROM site_settings\n WHERE data_type = 17\n UNION\n SELECT id, value::integer\n FROM site_settings\n WHERE data_type = 18 AND value != ''\n)\nINSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT site_settings_uploads.upload_id, 'SiteSetting', site_settings_uploads.id, uploads.created_at, uploads.updated_at\nFROM site_settings_uploads\nJOIN uploads ON uploads.id = site_settings_uploads.upload_id\nON CONFLICT DO NOTHING\n")
-> 0.0034s
== 20220330160747 CopySiteSettingsUploadsToUploadReferences: миграция завершена (0.0038s)
== 20220330160751 CopyBadgesUploadsToUploadReferences: миграция ==============
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT badges.image_upload_id, 'Badge', badges.id, uploads.created_at, uploads.updated_at\nFROM badges\nJOIN uploads ON uploads.id = badges.image_upload_id\nWHERE badges.image_upload_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0006s
== 20220330160751 CopyBadgesUploadsToUploadReferences: миграция завершена (0.0010s) =====
== 20220330160754 CopyGroupsUploadsToUploadReferences: миграция ==============
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT groups.flair_upload_id, 'Group', groups.id, uploads.created_at, uploads.updated_at\nFROM groups\nJOIN uploads ON uploads.id = groups.flair_upload_id\nWHERE groups.flair_upload_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0050s
== 20220330160754 CopyGroupsUploadsToUploadReferences: миграция завершена (0.0055s) =====
== 20220330160757 CopyUserExportsUploadsToUploadReferences: миграция =========
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT user_exports.upload_id, 'UserExport', user_exports.id, uploads.created_at, uploads.updated_at\nFROM user_exports\nJOIN uploads ON uploads.id = user_exports.upload_id\nON CONFLICT DO NOTHING\n")
-> 0.0013s
== 20220330160757 CopyUserExportsUploadsToUploadReferences: миграция завершена (0.0041s)
== 20220330164740 CopyThemeFieldsUploadsToUploadReferences: миграция =========
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT theme_fields.upload_id, 'ThemeField', theme_fields.id, uploads.created_at, uploads.updated_at\nFROM theme_fields\nJOIN uploads ON uploads.id = theme_fields.upload_id\nWHERE type_id = 2\nON CONFLICT DO NOTHING\n")
-> 0.0006s
== 20220330164740 CopyThemeFieldsUploadsToUploadReferences: миграция завершена (0.0010s)
== 20220404195635 CopyCategoriesUploadsToUploadReferences: миграция ==========
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT categories.uploaded_logo_id, 'Category', categories.id, uploads.created_at, uploads.updated_at\nFROM categories\nJOIN uploads ON uploads.id = categories.uploaded_logo_id\nWHERE categories.uploaded_logo_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0095s
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT categories.uploaded_background_id, 'Category', categories.id, uploads.created_at, uploads.updated_at\nFROM categories\nJOIN uploads ON uploads.id = categories.uploaded_background_id\nWHERE categories.uploaded_background_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0004s
== 20220404195635 CopyCategoriesUploadsToUploadReferences: миграция завершена (0.0103s) =
== 20220404201949 CopyCustomEmojisUploadsToUploadReferences: миграция ========
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT custom_emojis.upload_id, 'CustomEmoji', custom_emojis.id, uploads.created_at, uploads.updated_at\nFROM custom_emojis\nJOIN uploads ON uploads.id = custom_emojis.upload_id\nWHERE custom_emojis.upload_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0032s
== 20220404201949 CopyCustomEmojisUploadsToUploadReferences: миграция завершена (0.0036s)
== 20220404203356 CopyUserProfilesUploadsToUploadReferences: миграция ========
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT user_profiles.profile_background_upload_id, 'UserProfile', user_profiles.user_id, uploads.created_at, uploads.updated_at\nFROM user_profiles\nJOIN uploads ON uploads.id = user_profiles.profile_background_upload_id\nWHERE user_profiles.profile_background_upload_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0017s
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT user_profiles.card_background_upload_id, 'UserProfile', user_profiles.user_id, uploads.created_at, uploads.updated_at\nFROM user_profiles\nJOIN uploads ON uploads.id = user_profiles.card_background_upload_id\nWHERE user_profiles.card_background_upload_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0011s
== 20220404203356 CopyUserProfilesUploadsToUploadReferences: миграция завершена (0.0033s)
== 20220404204439 CopyUserAvatarsUploadsToUploadReferences: миграция =========
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT user_avatars.custom_upload_id, 'UserAvatar', user_avatars.id, uploads.created_at, uploads.updated_at\nFROM user_avatars\nJOIN uploads ON uploads.id = user_avatars.custom_upload_id\nWHERE user_avatars.custom_upload_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0200s
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT user_avatars.gravatar_upload_id, 'UserAvatar', user_avatars.id, uploads.created_at, uploads.updated_at\nFROM user_avatars\nJOIN uploads ON uploads.id = user_avatars.gravatar_upload_id\nWHERE user_avatars.gravatar_upload_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0069s
== 20220404204439 CopyUserAvatarsUploadsToUploadReferences: миграция завершена (0.0276s)
== 20220404212716 CopyThemeSettingsUploadsToUploadReferences: миграция =======
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT theme_settings.value::int, 'ThemeSetting', theme_settings.id, uploads.created_at, uploads.updated_at\nFROM theme_settings\nJOIN uploads ON uploads.id = theme_settings.value::int\nWHERE data_type = 6 AND theme_settings.value IS NOT NULL AND theme_settings.value != ''\nON CONFLICT DO NOTHING\n")
-> 0.0025s
== 20220404212716 CopyThemeSettingsUploadsToUploadReferences: миграция завершена (0.0030s)
== 20220526203356 CopyUserUploadsToUploadReferences: миграция ================
-- execute("INSERT INTO upload_references(upload_id, target_type, target_id, created_at, updated_at)\nSELECT users.uploaded_avatar_id, 'User', users.id, uploads.created_at, uploads.updated_at\nFROM users\nJOIN uploads ON uploads.id = users.uploaded_avatar_id\nWHERE users.uploaded_avatar_id IS NOT NULL\nON CONFLICT DO NOTHING\n")
-> 0.0227s
== 20220526203356 CopyUserUploadsToUploadReferences: миграция завершена (0.0234s) =======
[2022-06-09 09:02:11] Переподключение к базе данных...
[2022-06-09 09:02:12] Перезагрузка настроек сайта...
[2022-06-09 09:02:12] Отключение исходящей почты для неадминистративных пользователей...
[2022-06-09 09:02:14] Отключение режима только для чтения...
[2022-06-09 09:02:14] Очистка кэша категорий...
[2022-06-09 09:02:14] Перезагрузка переводов...
[2022-06-09 09:02:14] Переназначение загрузок...
[2022-06-09 09:02:14] Восстановление загрузок, это может занять некоторое время...
[2022-06-09 09:03:05] ИСКЛЮЧЕНИЕ: 509 из 1823 загрузок не были перенесены в S3. Перенос в S3 не удался для базы данных 'default'.
[2022-06-09 09:03:05] /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/file_store/s3_store.rb:328: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:61:in `run'
/var/www/discourse/script/spawn_backup_restore.rb:23:in `restore'
/var/www/discourse/script/spawn_backup_restore.rb:36:in `block in <main>'
/var/www/discourse/script/spawn_backup_restore.rb:4:in `fork'
/var/www/discourse/script/spawn_backup_restore.rb:4:in `<main>'
Может ли кто-нибудь подсказать, в чём проблема и как я могу восстановить сервер из резервных копий Amazon S3?