@RGJ بالمثل، أنا صادق تمامًا: إذا كان أي شخص يعرف بشكل قاطع كيفية تجنب هدر الوقت في إعادة بناء جميع الصور، فأنا مع ذلك تمامًا. ولو كنت مطورًا مخضرمًا في Discourse وكنت أعرف كيفية القيام بذلك بسهولة، لكانت هذه هي الخطوة الأولى التي كنت سأقوم بها.
أعتقد أن الانتقال بعيدًا عن S3 ليس حالة شائعة لمن يملكون عددًا كبيرًا من الصور، لذا من الصعب أن يكون ذلك يستحق الوقت مقارنةً بإضافة ميزات أكثر فائدة بشكل عام إلى Discourse. كان لدي ما يقارب 100 جيجابايت من الملفات المرفوعة عند الاستيراد من Google+ إلى MakerForums، وقد اخترنا S3 بفكرة أنه من الممكن أن ينتقل الكثير من الأشخاص من تلك المجتمعات إلى MakerForums، لكن في النهاية انتقلت بضع مجتمعات فقط بنشاط، لذا لم يكن النمو المستمر يدعم البقاء على S3 في النهاية. أتوقع أن هذه حالة شاذة إلى حد ما، وإعادة معالجة الصور هي تكلفة لمرة واحدة فقط.
أخيرًا، أنا ممتن جدًا لفتحك لهذا الموضوع من الأساس، لأنه لولا ذلك كان من السهل جدًا أن أفوت التحميلات غير المرتبطة بالمنشورات.
…
@RGJ أنت محق بوضوح في أن التدمير وإعادة الإنشاء ليس أمرًا جيدًا. لقد أضفت تحققًا: raise "Error: upload url #{url} changed to #{new_upload.short_url}, should be unchanged." if url != new_upload.short_url والذي على الأقل يبلغ عن مشاكل في المصدر التالف. تسببت انقطاع Digital Ocean Spaces اليوم في إرسال بيانات تالفة لي، مما أثار هذا الخطأ في العديد من التحميلات — ولا أعرف كم منها. ولكن لأن النظام قد دمر بالفعل التحميل القديم، أصبح لدي الآن بعض الصفحات التالفة، ولم أدرك ذلك حتى فقدت سجل التمرير (scrollback) الذي يحتوي على السجلات التي تخبرني بالصفحات التالفة، لذا لا يمكنني حتى الدخول وإصلاحها يدويًا من نسخة احتياطية.
لذا، بينما يُعد عملي تحسينًا على الطريقة القديمة لأنه على الأقل يبلغ عن بعض الأخطاء، فسيكون من الأفضل بكثير تنزيل الملفات، والتحقق من تجزئات SHA1 للملفات المحملة، وكتابتها كملفات محلية. في غضون ذلك، قمت بتعديل طلب السحب الخاص بي (PR) لإيقاف الهجرة عند أي خطأ غير مُعالج لتقليل فقدان البيانات على الأقل.
ما زلت أعتقد أن عملي يجب أن يُدمج كتحسين باريتو (Pareto improvement)، لأنه لا يجعل الأمور أسوأ بل يجعلها أفضل، لكن سيكون من الأفضل بكثير القيام بذلك بالطريقة الصحيحة. أعتقد أن ذلك يتطلب كتابة ملف lib/file_store/from_s3_migration.rb ليعمل بالتوازي مع lib/file_store/to_s3_migration.rb، لكنني لست مؤهلاً للقيام بذلك.
بما أن طلب السحب الخاص بي لم تتم مراجعته بعد، فقد أضفت المزيد إليه. لقد أضفت مهمة uploads:report_missing_uploads تبحث في raw عن حالات upload://... حيث لا يوجد كائن التحميل المرفق. على الأقل في حالتي، مع وجود نسخ احتياطية، سأتمكن من البحث في نسخي الاحتياطية وإيجاد الملفات اليتيمة واستعادتها إلى الموقع، ثم إعادة طباعة (rebake) تلك المنشورات لاستعادة الصور المفقودة. لقد عثرت على 678 منها للبحث عنها في النسخ الاحتياطية، وقد عثرت حتى الآن على جميعها ما عدا 10، لذا أنا سعيد لكتابة الاختبار! سأحتاج إلى التعامل مع ذلك قبل أن أنتقل إلى المرحلة التي أعيد فيها طباعة المنشورات المتبقية.
…
لقد أكملت مرحلتي الأولى من الهجرة، دون شمل إعادة طباعة المنشورات المتأثرة بالتحميلات المشتركة، ودون شمل التحميلات غير المرتبطة بالمنشورات. بعد إكمال نسخة احتياطية عن بعد أخرى، أخطط لاختبار تلك الميزات أيضًا وإضافتها إلى طلب السحب الخاص بي.
…
لقد بدأت الآن اختبار المراحل التالية من الهجرة، وهي إعادة الطباعة وهجرة التحميلات غير المرتبطة بالمنشورات. كانت أول درس لي هو أن إعادة الطباعة كخطوة تالية تفشل بسبب صور الرموز الشخصية (avatars) غير المرتبطة بالمنشورات في المنشورات المقتبسة، لذا يجب أن تكون إعادة طباعة المنشورات هي الخطوة الأخيرة.
اكتشاف تالي: شكرًا لك على قيود المفاتيح الخارجية! اكتشفت أثناء هجرة التحميلات غير المرتبطة بالمنشورات أنني بحاجة إلى هجرة الملفات الشخصية (profiles) على الأقل قبل هجرة التحميلات غير المرتبطة بالمنشورات بشكل عام.
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "uploads" violates foreign key constraint "fk_rails_1d362f2e97" on table "user_profiles"
كانت هجرة الملفات الشخصية محيرة لأنني اضطررت لهجرة صورتين مرفقتين بالملف الشخصي، ولكن في بعض الحالات استخدم الأشخاص نفس الصورة لكليهما، لذا اضطررت للقيام بذلك العمل على ثلاث مراحل. لقد نجحت في هجرة جميع الملفات الشخصية في موقعي مع عناوين URL الخاصة بـ S3.
لقد هجرت جميع التحميلات غير المرتبطة بالمنشورات وغير المرتبطة بالملفات الشخصية. @RGJ إذا كنت ترغب في تجربة الفرع الذي نشرته، فهو محدث بعملي. كل ما فيه قد تم استخدامه الآن لهجرة موقع مكتمل.
…
@cvx لا أعرف متى ستتاح لك فرصة المراجعة، ولكن بدون طلب السحب الخاص بي، فإن migrate_from_s3 مليء بالتأكيد بـ أخطاء تدمير البيانات الصامتة. ما قمت به ليس مثاليًا، لكنه يحمي من العديد من الأخطاء التي واجهتها عمليًا.
لقد قمت بكل العمل الذي أعتزم القيام به حاليًا هنا. لقد هجرت موقعي، مما يعني أنني لا أستطيع حتى تقييم أي تغييرات مطلوبة بفعالية. إذا رفضتم هذا الطلب، فأقترح بشدة أن تقوموا بدلاً من ذلك بحذف عملية الهجرة الحالية لأنها ستقوم بتدمير البيانات صامتًا للمستخدمين.
بشأن طلب السحب، أحيانًا أحصل على فشل في الاختبارات في CI (كما هو الإصدار الحالي) يشبه هذا:
7867 examples, 0 failures, 11 pending, 1 error occurred outside of examples
##[error]Process completed with exit code 1.
هذا لا يتكرر محليًا لدي (حتى الآن) ولا أرى أي معلومات في سجلات CI لتقول ما الخطأ في CI، لذا لن أضيع المزيد من وقتي في محاولة العبث باستكشاف مخرجات CI بحثًا عن معلومات مخفية.
ملاحظة أخيرة: بعد إكمال الهجرة، اكتشفنا أن صور الملفات الشخصية لبعض المستخدمين فقدت أثناء الهجرة، وهم يستعيدونها يدويًا. أظن أن كودًا إضافيًا كان مطلوبًا لنجاح ذلك، لكن بما أنني لم أكتشف ذلك إلا بعد فوات الأوان، فلا أملك حالة اختبار للتحقق من ذلك. لذا فهذا خطأ متبقي قد يسبب مشاكل في بعض التكوينات، لكنني لم أعد في وضع يسمح لي بكتابة الإصلاح الإضافي.