الأولوية/الشدة:
عالية للنسخ المستضافة ذاتيًا التي تستخدم تخزين نسخ احتياطية متوافق مع S3، حيث تفشل النسخ الاحتياطية المجدولة بعد إنشاء الأرشيف.
المنصة:
Discourse مستضاف ذاتيًا على أحدث فرع.
الإصدار الحالي المباشر عند الملاحظة: v2026.4.0-latest
Ruby: 3.4.0
aws-sdk-s3: 1.182.0
الوصف:
تفشل النسخ الاحتياطية إلى Cloudflare R2 في الخطوة النهائية “جاري تحميل الأرشيف…”.
يتم إكمال عملية تصدير قاعدة البيانات وإنشاء الأرشيف المحلي بنجاح، لكن عملية التحميل متعدد الأجزاء للأرشيف النهائي تفشل.
النتيجة الفعلية:
يفشل النسخ الاحتياطي مع الرسالة:
EXCEPTION: multipart upload failed: undefined method 'downcase' for nil
يتضمن تتبع المكدس:
aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb
lib/backup_restore/s3_backup_store.rb:48
lib/backup_restore/creator.rb:434
النتيجة المتوقعة:
يجب أن يتم تحميل أرشيف النسخ الاحتياطي بنجاح إلى مخزن النسخ الاحتياطي المتوافق مع S3 المُهيأ.
خطوات التكرار:
- قم بتكوين تخزين النسخ الاحتياطي لـ Cloudflare R2 باستخدام مسار النسخ الاحتياطي المتوافق مع S3.
- استخدم أرشيف نسخ احتياطي أكبر من عتبة التحميل متعدد الأجزاء.
- قم بتشغيل نسخة احتياطية يدوية أو مجدولة.
- راقب الفشل أثناء “جاري تحميل الأرشيف…”.
الإعدادات ذات الصلة:
- DISCOURSE_BACKUP_LOCATION=s3
- DISCOURSE_S3_ENDPOINT=https://.r2.cloudflarestorage.com
- DISCOURSE_S3_FORCE_PATH_STYLE=true
- DISCOURSE_S3_BACKUP_BUCKET=
- AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
- AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
مقتطف من تتبع المكدس الملاحظ:
algorithm = resp.context.params[:checksum_algorithm]
k = "checksum_#{algorithm.downcase}".to_sym
هذا يشير إلى أن checksum_algorithm هو nil في مسار التحميل متعدد الأجزاء.
سياق إضافي:
هناك موضوع حديث مشابه على Meta للنسخ الاحتياطية إلى Backblaze B2:
أيضًا، تبدو مدخلات سجل التغييرات لـ aws-sdk-s3 بعد الإصدار 1.182.0 ذات صلة:
- 1.201.0: إصلاح التحميل متعدد الأجزاء لاحترام وضع
request_checksum_calculationعندwhen_required - 1.210.2: العودة إلى استخدام تجزئات الطلب عبر الرؤوس عند استخدام نقاط نهاية مخصصة أو موفري نقاط نهاية لعمليات PutObject و UploadPart
يبدو أن Discourse main لا يزال يقيد aws-sdk-s3 حاليًا على الإصدار 1.182.0:
https://raw.githubusercontent.com/discourse/discourse/main/Gemfile.lock