الافتراضات ضائعة بعد الاستعادة. كيف يمكن استعادتها؟

صباح الخير @ariznaf،

قبل التوصل إلى هذا الاستنتاج، هل يمكنك الرجاء الانتقال إلى جميع التثبيتات الخاصة بك، والذهاب إلى المجلد المشترك في كل تثبيت، وتنفيذ الأمر التالي لكل تثبيت ثم مشاركة النتائج؟

# du -sh uploads

على سبيل المثال، في تثبيتاتنا، قمت بتنفيذ ما يلي:

التثبيت الأصلي:

# du -sh uploads
2.5G uploads

تثبيت Socket فقط (قبل إصلاح المشكلة):

# du -sh uploads
444K uploads

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

إذا قمت بفحص جميع مجلدات uploads المختلفة باستخدام du -sh uploads في جميع المجلدات المشتركة، فسيوفر ذلك دليلًا قيمًا حول ما يحدث.

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

إذا كانت جميعها متطابقة (وهو أمر غير مرجح)، فإن المشكلة تصبح أكثر إثارة للاهتمام :slight_smile:

لقد عثرت على المشكلة (وليس الحل).
المشكلة ليست في عملية الاستعادة بحد ذاتها، بل في تغيير اسم الخادم.

دعني أشرح كيف قمت بالاستعادة (فقط في حال وجود أي خطوة مفقودة).

قامت بتحميل نسخة جديدة من discourse من github.
نفذت عملية docker-setup.
قبل تشغيل التطبيق والمضي قدمًا في الاستعادة، قمت بتحرير ملف app.yml لتكوين الوصول عبر socket.
وتغيير اسم المضيف إلى b.domain.com (في الأصل كان a.domain.com).

قمت بتكوين عكسي nginx باستخدام SSL لتوجيه حركة مرور https عبر المنفذ 443 إلى socket الخاص بـ discourse.
ثم أعيد بناء التطبيق (launcher rebuild app) وأعدت تشغيل nginx (service nginx restart).
دخلت إلى https://b.domain.com لإجراء التكوين الأولي لـ discourse.
قمت بتكوينه للاستعادة من S3 واستعدت آخر نسخة احتياطية تم إنشاؤها من قاعدة البيانات والملفات المرفوعة (بدون صور مصغرة).
بعد الاستعادة، يتم تسجيل خروجك تلقائيًا.
ثم قمت بتحرير ملف app.yml لنسخه من الموقع القديم (للحصول على نفس التكوين والإضافات).
وتغيير اسم المضيف إلى b.domain.com في ملف app.yml.

أعدت بناء التطبيق مرة أخرى وأعدت تشغيل nginx.

المشكلة لا تزال قائمة: صور الملفات الشخصية (الصور المصغرة) لجميع المستخدمين الذين غيروا ملفاتهم الشخصية قد استبدلت بصورة الملف الشخصي البيضاء الافتراضية.
كما أن شعارنا في الزاوية العلوية اليسرى مفقود أيضًا.

@Stephen كان خيار force_https مفعّلًا (كما كان في الخادم الأصلي، دون مشاكل). حاولت تفعيله وإلغاء تفعيله، لكن دون أي تأثير. تركته مفعّلًا، لأننا نريد الوصول إلى موقعنا عبر https (على أي حال، حركة مرور http:80 يتم إعادة توجيهها بشكل دائم إلى https:443 في تكوين nginx لدينا).

@riking استخدمت sidekiq وأطلقت مهمة avatarmissing التي بدت أنها اكتملت بنجاح في بضع ميلي ثوانٍ. فقط للتأكد من أن العملية قد تستغرق وقتًا طويلاً، انتظرت حوالي 24 ساعة لأرى ما إذا كانت صور الملفات الشخصية قد تم إعادة بنائها.
لكن اليوم لا تزال المشكلة نفسها: لا توجد صور ملفات شخصية (للأشخاص الذين قاموا برفع صورة ملف شخصي) ولا توجد صورة الشعار.

بعد ذلك، حاولت التحقق مما إذا كانت المشكلة ناتجة عن تغيير الاسم، كما اقترح @Stephen.

عدلت اسم المضيف في ملف app.yml و nginx إلى a.domain.com (الاسم الأصلي) وأعدت بناء التطبيق وأعدت تشغيل nginx.
قمت بتعديل ملف hosts المحلي ليوجه a.domain.com إلى عنوان IP للخادم الجديد، وحاولت إجراء عملية ping للتأكد من أنه يتصل بالعنوان الجديد.

وها هو الحل! ظهرت الصور الشخصية وملفاتنا الشخصية.

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

على أي حال، المشكلة ليست في عملية الاستعادة أو الحاجة إلى إعادة رفع الصور بسبب نوع من التلف.

المشكلة هي تغيير اسم الخادم.

والسؤال الآن هو: كيف يمكن نقل منتدى discourse من نطاق/اسم مضيف إلى آخر؟

لقد حاولت تغيير اسم المضيف مرة أخرى إلى b.domain.com.

لم يفلح الأمر.

يبدو أنه عند استخدام الاسم القديم يعمل (لكنني أشك الآن في أنه يحصل على الصور والأشياء من الخادم القديم الذي لا يزال متصلًا بالإنترنت، حيث أتلقى منشورات جديدة وإشعارات عن منشورات جديدة في الخادم القديم، حتى لو قمت بتغيير عنوان IP لـ a.domain.com في ملف المضيفين الخاص بي).

لقد اتبعت التعليمات في هذا المنشور لتغيير اسم المضيف

كنت أعتقد أن إعادة توجيه discourse من a.domain.com إلى b.domain.com سيحل المشكلة.
حتى أنني نفذت أمر rake posts:rebake، لكن النتيجة كانت نفسها.

لقد فقدت الرموز التعبيرية والشعار، كما أن الصور المضمنة في المنشورات فقدت أيضًا.

أخيرًا، كما اقترح @neounix، قمت بفك ضغط جميع الملفات المرفوعة مرة أخرى لاستبدال الوجهة في shared/standalone/uploads/ لكن دون جدوى، والنتائج لا تزال نفسها.

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

جميع البيانات والمنشورات منذ بداية المنتدى قبل أشهر؟

كما ذكرت سابقًا، تمكنت من نقل الخادم إلى خادم آخر عن طريق إيقاف الخادم، ونسخ جميع البيانات إلى خادم جديد، ثم إعادة تشغيله.

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

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

لا أستطيع الانتظار حتى يحدث عطل في الخادم لأرى ما إذا كان بإمكاني استعادته أم لا.

اختبارات الاستعادة حتى الآن انتهت بنوع من المشكلة، وأصبحت النظام غير وظيفي، حيث فقدت الصور أو أشياء أخرى.

في أعقاب هذه السلسلة:

https://meta.discourse.org/t/postgresql-12-update/151236/193

لقد جربت طريقة “النسخ الاحتياطي والاستعادة على مثيل ديسكورس مختلف” وأصبحت الآن أواجه هذه المشكلة. جرّبت كل حيلة معروفة (عملية Sidekiq Job، وإعادة البناء Rebake)… هل هناك أي “دليل” حول ما قد يكون سببًا لهذه المشكلة؟ فقط لأتمكن من محاولة اكتشاف شيء ما.

(شيء واحد يجب أن أعتز به لكم جميعًا: مع كل هذا، انتقلت من “نعم، أنا أفهم الأمر إلى حد ما” إلى درجة دكتوراه في PostgreSQL، ودكتوراه في Redis… :stuck_out_tongue: ما أحتاجه فقط هو إتقان Ruby وبيئات التطوير المحلية، وعندها قد أكون مفيدًا للمجتمع :P)

هل اختفت جميع الصور الرمزية أم جزء منها فقط؟ الصور الرمزية المخصصة هي في الأساس uploads، فهل تعمل الـ uploads الأخرى كما هو متوقع؟

انتقل إلى وحدة تحكم Rails وتحقق من سجل الصورة الرمزية غير العاملة في قاعدة البيانات.. هل تحتوي على URL، وحجم الملف، والعرض، والارتفاع، والامتداد الصحيحين؟

User.find_by_username('Overgrow').user_avatar
User.find_by_username('Overgrow').uploaded_avatar

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

OptimizedImage.where(upload_id: upload_id).where(version: 2)

أولاً، شكراً جزيلاً لمساعدتك @Overgrow.

كانت جميع الرموز التعبيرية والصور الرمزية (بل وحتى صور الموقع، مثل العناوين وما إلى ذلك) “موجودة” ولكنها غير مرئية. بالنسبة للعناصر غير المتعلقة بالصور الرمزية، تظهر وكأنها مكسورة، أما بالنسبة للصور الرمزية، فتظهر كعنصر نائب رمادي. تمكن بعض الأشخاص من مجرد تحميل صورة جديدة، وهذه الصور مرئية.

في المحاولة الأولى لتشغيل الأمر، حصلت على:

FATAL:  the database system is in recovery mode

إذن… هذا هو الوضع :eyes: (لدي الكثير من “انقطاعات الاتصال”، لذا أفترض أن الأمر يتعلق بقاعدة البيانات، ربما؟)

ولكن بعد الإصرار في النهاية:

User.find_by_username(‘Overgrow’).user_avatar

=> #<UserAvatar:0x000055702722d200
 id: 4,
 user_id: 3,
 custom_upload_id: 20504,
 gravatar_upload_id: 12240,
 last_gravatar_download_attempt: Thu, 21 May 2020 10:16:55 UTC +00:00,
 created_at: Sat, 30 May 2019 16:33:16 UTC +00:00,
 updated_at: Thu, 21 May 2020 10:16:55 UTC +00:00>

(حاولت تحميل صورة جديدة اليوم لكنها لا تعمل).

User.find_by_username(‘Overgrow’).uploaded_avatar

=> #<Upload:0x00005555cd911b58
 id: 20504,
 user_id: 3,
 original_filename: "16_2.png.jpg",
 filesize: 56220,
 width: 360,
 height: 360,
 url: "/uploads/default/original/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8.jpeg",
 created_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 updated_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 sha1: "63347a46c0ca945f53613722a73c233484d642c8",
 origin: nil,
 retain_hours: nil,
 extension: "jpeg",
 thumbnail_width: 360,
 thumbnail_height: 360,
 etag: nil,
 secure: false,
 access_control_post_id: nil,
 original_sha1: nil>

OptimizedImage.where(upload_id: 20504).where(version: 2)

=> [#<OptimizedImage:0x000056366a01c1a0
  id: 95962,
  sha1: "5a32b5cc3e6f5c58d88a3c92a23076980a8ce840",
  extension: ".jpeg",
  width: 200,
  height: 200,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg",
  filesize: 28916,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a0741e8
  id: 95942,
  sha1: "ee353c9e23511b471e1a59c1f71a2ded3e366b1e",
  extension: ".jpeg",
  width: 20,
  height: 20,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_20x20.jpeg",
  filesize: 1270,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074120
  id: 95943,
  sha1: "944fa9fc542a79a5c50394c75022bf84ace297e5",
  extension: ".jpeg",
  width: 30,
  height: 30,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_30x30.jpeg",
  filesize: 1952,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074058
  id: 95944,
  sha1: "983490e58bed58c971ffa44e440b02ce3ea72bba",
  extension: ".jpeg",
  width: 40,
  height: 40,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_40x40.jpeg",
  filesize: 2695,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a07bf60

إذن ظاهرياً الصور موجودة، لكنها لا تظهر. فقط عنصر نائب افتراضي رمادي للصورة الرمزية.

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

ماذا تحصل عليه عند تتبع روابط التحميلات التي سرّدتَها يدويًا؟

إذا وضعت /uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg (أي) بعد عنوان URL الخاص بـ Discourse الخاص بي؟ أحصل على خطأ 404، غير موجود.

إذًا… هل هي غير موجودة؟ (أسأل على أمل :P)

تحقق أيضًا من بعض عناوين URL للملفات من /uploads/default/original وليس فقط من /uploads/default/optimized.

404 … هذا يعني أنك بحاجة إلى التحقق من مجلد uploads داخل /var/discourse/shared/standalone على نظام الملفات والبحث عن مكان الملفات القديمة الفعلية (إذا كانت موجودة). عندما تجدها، حاول مقارنة الموقع بالملفات التي تم تحميلها حديثًا (تلك التي تعمل).

يمكنك أيضًا استعادتها يدويًا من النسخة الاحتياطية.

شكرًا لك على الشرح.

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

الجزء الغريب هو أن لدي أشخاصًا يحاولون تحميل ملفات جديدة، وهذه الملفات الجديدة لا تعمل أيضًا. عندما تفحص باستخدام الأوامر التي أعطيتها لي، يمكنك رؤية مسار غير موجود أيضًا. كيف يقوم Discourse بـ “تعيين” هذا؟ لأن الشيء الذي لا أستطيع فهمه تمامًا هو أن الملفات مفقودة (على الرغم من أنه كان من المفترض أن ينقلها النسخ الاحتياطي)، لكن التحميلات الجديدة تذهب إلى مسارات وهمية؟

تحقق من مجلد tombstone داخل مجلد uploads - هل توجد بعض الملفات المفقودة هناك؟

المجلد الوحيد الذي أراه داخل uploads هو default… هل مجلد tombstone مخصص للملفات الملغاة أو شيء من هذا القبيل؟

أيضًا، معلومة إضافية: اتضح أنه إذا حاول المستخدم رفع نفس الصورة التي لديه بالفعل (حتى لو غيّر اسم الملف، وأعتقد بناءً على ما أراه من تلك الاستعلامات أن ذلك يعتمد على التجزئة hash)، فلن تُحمّل الصورة وستظهر فارغة؛ فبمجرد الحفظ، ستظهر علامة التبويب الرمادية.

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

هذا سلوك طبيعي. يتم تخزين تجزئة ملف البيانات في قاعدة البيانات لتجنب تكرار الصور.

ماذا يحدث إذا قمت برفع صورة عبر محرر الكتابة؟ هل يكتمل الرفع؟ هل تظهر في لوحة المعاينة؟

إذا كتبت رسالة وأدرجت صورة فيها، فستظهر في لوحة المعاينة وسيتم إكمال التحميل، نعم، هذا هو السلوك الطبيعي.

إذن في أي نقطة بالضبط تتوقف الصورة عن الظهور؟

تحقق من عنوان URL للصورة التي تراها وابحث عنها في نظام الملفات.

تحقق من عناوين URL للصور التي لا تعمل (من خلال أدوات مطوري الويب في المتصفح). ما هو الاختلاف؟

ربما تشير إلى نطاق مختلف.

في الرسالة الأولى كنت أقصد الصور الرمزية (الأفاتار) تحديدًا (من خلال ملف المستخدم)، أما الثانية فهي في المحرر.

إذًا، في رسالة عادية، إذا قمت بسحب وإفلات الصورة أو ضغطت على زر “رفع صورة”، فستعمل بسلاسة كما هو معتاد.

باختصار:

  • لا تظهر الصور الرمزية، بل يظهر فقط عنصر نائب.
  • الرموز التعبيرية المخصصة لا تظهر أيضًا.
  • صور الموقع (مثل الشعار، إلخ) لم تكن تظهر أيضًا.
  • إذا قمت برفع صور من المحرر، فستعمل بشكل جيد.
  • إذا حاولت رفع نفس الصورة الرمزية التي كانت لديك قبل الحادثة، فلن تعمل. السلوك هو: سيتم رفع الصورة، ثم في المربع الذي تختار فيه ما إذا كنت تريد حرفًا افتراضيًا، أو جرافاتار، أو رفع صورة، سيظهر كمربع فارغ. عند تأكيد اختيارك وإعادة تحميل الصفحة، ستحصل على العنصر الناط الرمادي.

أيضًا:

  • لا يوجد مجلد Tombstone.
  • الصور القديمة موجودة في مجلدات (كما هو موضح في الاستعلامات التي زودتني بها) لا توجد.

دعني أتحقق من مسألة النطاق. كملاحظة، عندما كنت أقرأ للحصول على معلومات، جربت ما يلي:

  • تشغيل مهمة CreateMissingAvatars من Sidekiq → دون نجاح.
  • إعادة بناء جميع المنشورات (نعم، هذا نوع من المبالغة) → دون نجاح.
  • بناءً على هذا الموضوع، وبما أنني استخدمت نطاقًا مختلفًا (في الواقع نطاقًا فرعيًا) لاختبار الاستعادة من نسخة احتياطية بينما كان الموقع الرئيسي غير متصل، ظننت أن بعض عناوين URL قد تكون خاطئة، لذا قمت بتشغيل الأمر التالي: discourse remap talk.foo.com talk.bar.com → دون نجاح.

@Iceman

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

من المثير جدًا (ورائع جدًا، في رأيي)، كيف يعمل مجدول وظائف Redis / Sidekiq عند تشغيلها بالتوازي، ولكن فقط واحدة منها “نشطة على جانب ويب المستخدم”:

آمل أن تجد هذا النقاش القصير مع مثال من الواقع مثيرًا للاهتمام. فقد قد يوفر قدرًا بسيطًا من البصيرة حول مجدول وظائف Discourse، وتحسين الصور، وصور المستخدمين بناءً على إعداداتنا:

أنا من المعجبين الكبار بكيفية استخدام Discourse لـ Redis / Sidekiq في جدولة الوظائف الخلفية؛ وأعتبر هذه إحدى نقاط القوة والفوائد الرئيسية لهيكلية برمجيات Discourse.

ملاحظة: تنطبق هذه المفاهيم أيضًا، بطرق دقيقة مختلفة، على مراحل مختلفة في عملية النسخ الاحتياطي والاستعادة وعمليات أخرى (تعتمد على الوقت)، لذا فمن الجيد فهم كيفية وأسباب جدولة Sidekiq للوظائف في الخلفية.

شكرًا لك على المعلومات يا @neounix، إنها مفيدة جدًا لفهم “الداخل” الخاص بـ Discourse من منظور “أنا أتعلم Rails لأتمكن من المساعدة، ولكن يا إلهي، منحنى التعلم صعب جدًا أثناء محاولة إصلاح تثبيتك الخاص” :stuck_out_tongue:

أركز حاليًا على Redis/Sidekiq لمحاولة فهم سبب عدم عمل بعض التضمينات منذ أنني أعتقد أن ذلك قد يكون مرتبطًا بـ “Bake”، لكنني لا أستطيع الجزم بذلك لأنني ما زلت في مرحلة التعلم فيما يتعلق بالتنقيح (أرجو ذلك).

بخصوص مشكلتي هنا، بفضل @Overgrow تمكنت من تحديد ما يلي:

  • في الواقع، عملية النسخ الاحتياطي قامت بنسخ الملفات في النسخة الاحتياطية ولكنها لم تستردها إلى تثبيت Discourse. بناءً على حالة و/أو إصلاحات مشاكلي الثلاث الأخرى، قد أحتاج إلى استعادة نسخة احتياطية أخرى على تثبيت آخر واختبار عملية النسخ الاحتياطي مرة أخرى، ولكن قد تكون هذه مشكلة تؤثر على الجميع، ولا أعرف ذلك بعد.

  • وبسبب ذلك، كان يحدث هذا السلوك الغريب.

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

ومع ذلك، تستمر المشاكل الأخرى (عدم القدرة على إعادة بناء حاوية البيانات، والتي لا أعرف شيئًا عنها، ومشكلتين تجعلانني أركز على Sidekiq والأحداث، لأنهما قد تُحلان بهذه الطريقة: عدم عمل بعض Oneboxes (YouTube تحديدًا) ووجود بعض الإشعارات حول “تعديلات كاذبة” تحدث بشكل متكرر لبعض المستخدمين، على الرغم من عدم حدوث أي تعديلات. لذا أعتقد أن التثبيت الجديد قد يحتوي على بعض المشاكل في أحداثه، وأنا أحاول اكتشاف ذلك. :man_shrugging: