استعادة الملفات المرفوعة في المواقع المتعددة إلى "الافتراضي" بدلاً من اسم قاعدة البيانات الفعلي

على أحدث إصدار تجريبي من Discourse، مع تثبيت Docker ودعم المواقع المتعددة.

أحاول استعادة نسخة احتياطية من قاعدة البيانات الأصلية REDACTED إلى قاعدة البيانات الحالية db8015. تنتهي الملفات المرفقة في default، سواء على نظام الملفات أو في قاعدة البيانات.

تحدث هذه المشكلة سواء تم تشغيل الاستعادة من الواجهة الرسومية (GUI) أو عبر سطر الأوامر باستخدام الأمر 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.

يبدو أن هذا الإصلاح قد تسبب في خلل في بيئة الإنتاج، @sam؟

السجلات:

[STARTED]
'DHSupport' بدأت عملية الاستعادة!
يتم تحديد حالة الاستعادة على أنها جارية...
التأكد من وجود المسار /var/www/discourse/tmp/restores/db8015/2019-10-11-104940...
نسخ الأرشيف إلى مجلد tmp...
فك ضغط الأرشيف، قد يستغرق هذا بعض الوقت...
لا يوجد ملف بيانات وصفية لاستخراجه.
التحقق من صحة البيانات الوصفية...
  الإصدار الحالي: 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 # الافتراضي
  optimized_images_exist = File.exist?(File.join(tmp_uploads_path, 'optimized'))

الحل المؤقت هو استخدام @current_db هنا، الذي لا يزال يحتوي على الاسم الصحيح، بدلاً من RailsMultisite::ConnectionManagement.current_db، لكن هذا لا يحل المشكلة الحقيقية المتمثلة في عدم عمل إعادة الاتصال بقاعدة البيانات بشكل صحيح.

أحتاج إلى التعمق أكثر لإيجاد السبب الجذري للمشكلة.

هل أنت متأكد من أن هذا يحدث بعد مهمة الهجرة؟

هذا الكود

  migrate_database
  puts "بعد الهجرة، قبل إعادة الاتصال #{RailsMultisite::ConnectionManagement.current_db}"
  reconnect_database

يُنتج المخرجات التالية

تحسين أيقونات الموقع... تم
بعد الهجرة، قبل إعادة الاتصال: الافتراضي
إعادة الاتصال بقاعدة البيانات...

ولكن عند التعليق على السطر

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

في ملف lib/tasks/db.rake

فإنه يُنتج المخرجات التالية

تحسين أيقونات الموقع... تم
بعد الهجرة، قبل إعادة الاتصال: db8015
إعادة الاتصال بقاعدة البيانات...

أنت محق. قمت بإزالة Rake::Task["db:migrate"].invoke من restorer.rb وحصلت على قاعدة البيانات الصحيحة طوال العملية.
أنت متقدم علي بخطوة، وخطةي الآن هي الدخول إلى مهمة الهجرة (migrate task) ومعرفة الخطوة التي تعطل العملية.
شكرًا لك على الإشارة إلى _dump، سأذهب مباشرة إليها لأرى ما يحدث بالداخل.

قمت بالتحقيق في الأمر لبعض الوقت، ولكنني حصلت أخيرًا على حل :slight_smile:

شكرًا لك!

بعد التفكير في الأمر أكثر، ماذا يعني بالضبط عند تشغيل db:dump على قاعدة بيانات ليست القاعدة الأساسية؟

ألا يجب أن يتخطى أمر db:dump ببساطة إذا لم تكن قاعدة البيانات هي الافتراضية؟

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