فشل الاستعادة بسبب فشل الترحيل إلى S3

نستضيف قاعدة بيانات Discourse الخاصة بنا ونحاول الترحيل إلى خادم جديد.

تم تحديث كلا الجانبين (القديم والجديد) إلى أحدث إصدار من Discourse (تمت إعادة بناء التطبيق على كلا الجانبين بفارق بضع دقائق)، وتم تنفيذ الترحيل إلى Postgresql الجديد بنجاح على الخادم القديم قبل بضع أيام. سأستبعد هذه الأشياء كمصدر لمشاكلنا.

جميع رفعاتنا مخزنة على تخزين كائنات متوافق مع S3 (Digitalocean Spaces)، لذا نظرياً يجب أن يكون الترحيل سهلاً. اعتقدت أنه إذا عملت جزء “المشاركات والفئات” من الاستعادة بشكل جيد، فإن الروابط إلى رفعات S3 يجب أن تعمل بشكل طبيعي، أليس كذلك؟

خطأ. كلما قمت باستعادة النسخة الاحتياطية لدينا على الخادم الجديد، ينجح جزء المشاركات بنسبة 100٪، ثم يفشل في جزء S3.

هذا هو الخطأ الذي نراه.

إعادة الاتصال بقاعدة البيانات...
إعادة تحميل إعدادات الموقع...
تعطيل رسائل البريد الإلكتروني الصادرة للمستخدمين غير الموظفين...
تشغيل seed fu...
تعطيل وضع القراءة فقط...
مسح ذاكرة التخزين المؤقت للفئات...
إعادة تحميل الترجمات...
إعادة تعيين رفعات الملفات...
استعادة الملفات المرفوعة، قد يستغرق هذا بعض الوقت...
ترحيل الملفات المرفوعة إلى S3 لـ 'default'...\nرفع الملفات إلى S3...
 - سرد الملفات المحلية
 => 3 ملفات
 - سرد ملفات S3
..................................................................................................................................................... => 148892 ملفًا
 - مزامنة الملفات مع S3
...
تحديث الروابط في قاعدة البيانات...
إزالة الصور المحسّنة القديمة...\nتعليم جميع المشاركات التي تحتوي على lightboxes لإعادة الخبز...
تم تعليم 29368 مشاركة لإعادة الخبز
EXCEPTION: rake posts:missing_uploads حدد 2274 مشكلة. فشل ترحيل S3 لقاعدة البيانات 'default'.
/var/www/discourse/lib/file_store/to_s3_migration.rb:132:in 'FileStore::ToS3Migration#raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:104:in 'FileStore::ToS3Migration#migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:384:in 'FileStore::ToS3Migration#migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:59:in 'FileStore::ToS3Migration#migrate'
/var/www/discourse/lib/file_store/s3_store.rb:372:in 'FileStore::S3Store#copy_from'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:69:in 'BackupRestore::UploadsRestorer#restore_uploads'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:49:in 'BackupRestore::UploadsRestorer#restore'
/var/www/discourse/lib/backup_restore/restorer.rb:179:in 'BackupRestore::Restorer#restore_uploads'
/var/www/discourse/lib/backup_restore/restorer.rb:72:in 'BackupRestore::Restorer#run'
script/discourse:242:in 'DiscourseCLI#restore'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor/command.rb:28:in 'Thor::Command#run'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor/invocation.rb:127:in 'Thor::Invocation#invoke_command'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor.rb:538:in 'Thor.dispatch'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor/base.rb:585:in 'Thor::Base::ClassMethods#start'
script/discourse:396:in '<top (required)>'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli/exec.rb:61:in 'Kernel.load'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli/exec.rb:61:in 'Bundler::CLI::Exec#kernel_load'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli/exec.rb:24:in 'Bundler::CLI::Exec#run'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli.rb:504:in 'Bundler::CLI#exec'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor/command.rb:28:in 'Bundler::Thor::Command#run'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in 'Bundler::Thor::Invocation#invoke_command'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor.rb:538:in 'Bundler::Thor.dispatch'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli.rb:35:in 'Bundler::CLI.dispatch'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor/base.rb:584:in 'Bundler::Thor::Base::ClassMethods#start'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli.rb:29:in 'Bundler::CLI.start'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/exe/bundle:28:in 'block in <top (required)>'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/friendly_errors.rb:118:in 'Bundler.with_friendly_errors'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/exe/bundle:20:in '<top (required)>'
/usr/local/bin/bundle:25:in 'Kernel#load'
/usr/local/bin/bundle:25:in '<main>'
محاولة التراجع...
جاري التراجع...	تنظيف الأشياء...
إسقاط الدوال من مخطط discourse_functions...
إزالة دليل '/var/www/discourse/tmp/restores/default/2026-08-11-075958' المؤقت...
إلغاء إيقاف sidekiq...
تحديد الاستعادة كمكتملة...
إعلام 'system' بنهاية الاستعادة...
انتهى!
[فشل]
تمت الاستعادة.

لدي بعض الأسئلة:

  • لماذا يفشل عندما يكون إعداد بيئة S3 الذي حفظناه في قاعدة البيانات غير متغير في المبدأ؟
  • لماذا ينهار بدلاً من إنشاء قائمة بالمشاكل الـ 2274 التي وجدها مع الملفات المرفوعة والتي يمكنني إدارتها بطريقة ما؟
  • لماذا يتراجع تلقائياً إلى قاعدة بيانات فارغة، تاركاًني في حالة حيرة؟
  • هل هناك طريقة لي لأتولى السيطرة، وأسمح له بإكمال الاستعادة بنجاح أو على الأقل عدم التراجع والسماح لي بالتعامل مع المشاكل التي وجدها مع الملفات المرفوعة؟

شكراً جزيلاً مقدماً على أي مساعدة!

لأنه يقوم فقط بعد الأعلام المرفقة مع النسخة الاحتياطية. هذه ليست العملية التي تقوم فعلياً باكتشاف المشكلات.

من الناحية المثالية، يجب عليك أولاً مسح أعلام الرفع المفقود على الخادم القديم، ثم إنشاء نسخة احتياطية جديدة.

يمكنك تشغيل مهمة ستقوم بإدراج ومحاولة إصلاح عمليات الرفع المفقودة على الخادم القديم (قد يستغرق ذلك بعض الوقت)

cd /var/discourse
./launcher enter app
VERBOSE=1 rake posts:missing_uploads

وعليك تحديد أي عناصر متبقية كتجاهل إذا كنت ترغب في المتابعة

GIVE_UP=1 VERBOSE=1 rake posts:missing_uploads

في هذه المرحلة، يمكنك إنشاء نسخة احتياطية جديدة واستعادتها.

ألف شكر على هذه الإجابة! إنها تساعدني كثيرًا لأنني على الأقل حصلت على قائمة كاملة بجميع المواضيع التي تواجه مشكلات في عمليات الرفع.

سأحاول إصلاح أكبر عدد ممكن منها، ولكن على الأقل لدي الآن طريقًا للأمام!