لديّ منتدى يعمل بشكل صحيح وأرغب في استعادة بعض الأمور التي تعطلت قبل بضعة أيام. أنا أستخدم AWS، لذا قمت بإنشاء صورة AMI للمنتدى العامل، ثم شغّلت مثيلًا جديدًا وحاولت استعادة نسخة احتياطية من قبل بضعة أيام، لكن العملية فشلت مع ظهور الرسائل التالية.
لا يمكن أن يكون السبب عدم تطابق الإصدار أو المخطط، لأن الخادم مبني من صورة جديدة للمنتدى العامل.
لقد حاولت إعادة البناء.
لقد حاولت أيضًا استعادة نسخة احتياطية من يوم واحد فقط سابقًا، ونفس المشكلة تكررت.
الشيء الغريب الوحيد الذي قمت به هو حذف ملفات PDF من مجلد التحميلات (…/uploads/original/1X/*.pdf) لتوفير بعض المساحة. سأحاول مرة أخرى دون تنفيذ هذه الخطوة، لكن يبدو من غير المرجح أن تكون هي السبب.
> [2019-11-30 01:17:44] بدأ 'admin' عملية الاستعادة!
> [2019-11-30 01:17:44] يتم الآن تحديد حالة الاستعادة على أنها جارية...
> [2019-11-30 01:17:44] التأكد من وجود /var/www/discourse/tmp/restores/default/2019-11-30-011744...
> [2019-11-30 01:17:44] جاري تنزيل الأرشيف إلى المجلد المؤقت...
> [2019-11-30 01:23:24] جاري فك ضغط الأرشيف، قد يستغرق ذلك بعض الوقت...
> [2019-11-30 01:27:52] لا يوجد ملف بيانات وصفية لاستخراجه.
> [2019-11-30 01:27:52] جاري التحقق من صحة البيانات الوصفية...
> [2019-11-30 01:27:52] الإصدار الحالي: 20191129144706
> [2019-11-30 01:27:52] الإصدار المراد استعادته: 20191120015344
> [2019-11-30 01:27:52] جاري استخراج ملف التصدير...
> [2019-11-30 01:50:57] أمر غير صالح \N
> [2019-11-30 01:50:57] أمر غير صالح \N
>
>
> < يتكرر حوالي 100 مرة >
>
> [2019-11-30 01:51:07] أمر غير صالح \N
> [2019-11-30 01:54:13] أمر غير صالح \N
> [2019-11-30 01:54:13] استثناء: فشل psql
> [2019-11-30 01:54:14] /var/www/discourse/lib/backup_restore/restorer.rb:331:in `restore_dump'
> /var/www/discourse/lib/backup_restore/restorer.rb:75:in `run'
> /var/www/discourse/lib/backup_restore.rb:166:in `block in start!'
> /var/www/discourse/lib/backup_restore.rb:163:in `fork'
> /var/www/discourse/lib/backup_restore.rb:163:in `start!'
> /var/www/discourse/lib/backup_restore.rb:22:in `restore!'
> /var/www/discourse/app/controllers/admin/backups_controller.rb:119:in `restore'
> إلخ...
أنا أميل إلى ربط تلك الأخطاء بتطابق إصدار PostgreSQL، لكنني رأيت أخطاء \N تلك في يوم آخر على نظام نفذت منه مساحة القرص (كنت أقوم باستعادة النسخة الاحتياطية إلى نفس النظام الذي أنشأ النسخة الاحتياطية). لم أكمل تشخيص المشكلة (كانت مشكلة غريبة أخرى كنت أعاني منها، وحلّت استعادة النسخة الاحتياطية إلى خادم آخر المشكلة؛ تساءلت عما إذا كانت الاستعادة إلى نفس الخادم كانت ستحل المشكلة).
لقد ذكرت أنك تعاني من ضيق المساحة. أشك في أن هذه هي المشكلة. تستخدم عملية الاستعادة مساحة كبيرة لأنها تقوم بفك ضغط النسخة الاحتياطية، وبالتالي تحتفظ بنسختين كاملتين منها بالإضافة إلى المساحة المطلوبة للاستعادة ولإمكانية التراجع عند الفشل.
الأمور تزداد سوءًا، لكن ربما نكون أقرب إلى المشكلة الحقيقية… بناءً على فرضية أنني أحتاج إلى مساحة تخزين أكبر، قمت بإنشاء مثيل جديد من صورتي، وهذه المرة بـ 100 جيجابايت بدلاً من 50 جيجابايت كما كان من قبل. (نسخ الاحتياطي بحجم 5 جيجابايت لكل منها ومخزنة على S3.) هذه المرة ظهرت لي رسالة خطأ صريحة: “No space left on device”. ومع ذلك، يُظهر أمر df وفرة من المساحة.
> [2019-11-29 22:42:58] التأكد من وجود /var/www/discourse/tmp/restores/default/2019-11-29-224258...
> [2019-11-29 22:42:58] تنزيل الأرشيف إلى مجلد tmp...
> [2019-11-29 22:45:46] فك ضغط الأرشيف، قد يستغرق هذا بعض الوقت...
> [2019-11-29 22:51:46] لا يوجد ملف بيانات وصفية لاستخراجه.
> [2019-11-29 22:51:46] التحقق من صحة البيانات الوصفية...
> [2019-11-29 22:51:46] الإصدار الحالي: 20191129144706
> [2019-11-29 22:51:46] الإصدار المستعاد: 20191108000414
> [2019-11-29 22:51:46] استخراج ملف التصدير...
> [2019-11-29 22:53:47] استثناء: لا توجد مساحة متبقية على الجهاز @ io_write - /shared/tmp/restores/default/2019-11-29-224258/dump.sql
> [ec2-user@ip-172-31-47-237 discourse]$ df / -h
> Filesystem Size Used Avail Use% Mounted on
> /dev/xvda1 99G 28G 71G 28% /
هل يمكن أن تكون المشكلة مرتبطة بملف التبديل (swap file)؟ مثيل EC2 هو من نوع t2.small بذاكرة 2 جيجابايت، لذا قمت منذ فترة طويلة بإنشاء ملف تبديل على المنتدى العامل. أفترض أن ملف التبديل سيتم نسخه تلقائيًا إلى المثيل الجديد. لست خبيرًا، لكنني أعتقد أن ملف التبديل موجود، لأنه لم يسمح لي بإنشاء ملف جديد، ولأن:
> /var/www/discourse# swapon -s
> Filename Type Size Used Priority
> /swapfile file 2097148 1024 -2
لا يحدث خطأ ‘لا يوجد مساحة متبقية على الجهاز’ فقط عندما تنفد الجيجابايتات من الجهاز، بل يحدث أيضًا عندما ينفد نظام الملفات من الـ inodes. لكن من الواضح أن هذه ليست المشكلة هنا. (فستكون iUse% عند 100% في هذه الحالة).
ما زال الأمر بلا جدوى. ظننت أنني سأحاول الاستعادة على مثيل Lightsail جديد، بدلاً من تشغيل صورة AMI لمثيل EC2 الذي يعمل بشكل صحيح. لا يزال الفشل يحدث، لكن الرسائل تختلف إلى حد ما.
كلا المثيلين القديم والجديد محدثان، وكلاهما تثبيت Docker قياسي، وكلاهما يشغل نفس إصدار PostgreSQL:
Creating missing functions in the discourse_functions schema
Cannot restore into different schema, restoring in-place
هل يمكن أن يكون ذلك مرتبطًا بالملحقات؟ لدي عدة ملحقات، مدعومة ومخصصة، مثبتة على موقع “المصدر”. بعضها يستخدم حقول مستخدم مخصصة. لقد حاولت الاستعادة إلى مواقع “وجهة” نظيفة مع وبدون ملحقات.
هل لديك أي تلميحات حول كيفية البدء في مقارنة المخططات؟
> [2019-12-07 04:51:36] 'admin' has started the restore!
> [2019-12-07 04:51:36] Marking restore as running...
> [2019-12-07 04:51:36] Making sure /var/www/discourse/tmp/restores/default/2019-12-07-045136 exists...
> [2019-12-07 04:51:36] Downloading archive to tmp directory...
> [2019-12-07 04:53:49] Unzipping archive, this may take a while...
> [2019-12-07 04:57:12] No metadata file to extract.
> [2019-12-07 04:57:12] Validating metadata...
> [2019-12-07 04:57:12] Current version: 20191129144706
> [2019-12-07 04:57:12] Restored version: 20191120015344
> [2019-12-07 04:57:12] Extracting dump file...
> [2019-12-07 04:59:10] Creating missing functions in the discourse_functions schema
> [2019-12-07 04:59:11] Cannot restore into different schema, restoring in-place
> [2019-12-07 05:05:02] ERROR: current transaction is aborted, commands ignored until end of transaction block
> [2019-12-07 05:05:03] ERROR: current transaction is aborted, commands ignored until end of transaction block
> < repeats about 100 times >
> [2019-12-07 05:05:03] ERROR: current transaction is aborted, commands ignored until end of transaction block
> [2019-12-07 05:05:03] EXCEPTION: psql failed
> [2019-12-07 05:05:03] /var/www/discourse/lib/backup_restore/restorer.rb:331:in `restore_dump'
> /var/www/discourse/lib/backup_restore/restorer.rb:75:in `run'
> /var/www/discourse/lib/backup_restore.rb:166:in `block in start!'
> /var/www/discourse/lib/backup_restore.rb:163:in `fork'
> /var/www/discourse/lib/backup_restore.rb:163:in `start!'
> /var/www/discourse/lib/backup_restore.rb:22:in `restore!'
> /var/www/discourse/app/controllers/admin/backups_controller.rb:119:in `restore'
> < rest of traceback >
من الواضح أن هناك مشكلة ما داخل PostgreSQL. هل راجعت سجلات (logs) النظام؟
احتمال بعيد: هل يمكن أن يكون هذا متعلقًا بالذاكرة؟ هل يمكنك محاولة مراقبة مخرجات free -m أثناء الاستعادة ورؤية ما إذا كان النظام ينفد من الذاكرة (الافتراضية)؟
أعلم أن هذا سؤال صعب لأننا لا نعرف ما هي المشكلة، ولكن بشكل عام، هل يجب أن أقوم بتثبيت الإضافات على الموقع الوجهة قبل محاولة الاستعادة؟ أم أن عملية الاستعادة تقوم بسحب وبناء الإضافات تلقائيًا؟
لقد قمت بإنشاء جهاز Lightsail جديد بسعة 20 دولارًا وذاكرة 4 جيجابايت. راقبت الأمر ‘free -m’ أثناء عملية الاستعادة. كانت الذاكرة الحرة والمتاحة دائمًا وفيرة.
تختلف الأخطاء المحددة اعتمادًا على ما إذا كانت الإضافات مثبتة أم لا، لكنها ترجع على الأرجح إلى نفس السبب الجذري. في هذه الحالة، لم قمت بتثبيت الإضافات قبل النسخ الاحتياطي. هناك فئتان من الأخطاء:
في سجلات postgres، أرى عددًا كبيرًا من هذه الرسائل، أحيانًا عند الحرف 34 وأحيانًا عند الحرف 41.
discourse@discourse ERROR: العلاقة “user_auth_tokens” غير موجودة عند الحرف 34
هذه الأخطاء ليس لها مخرج مقابله في صفحة المسؤول > النسخ الاحتياطي > السجل، وتستمر عملية الاستعادة لعدة دقائق رغم هذه الأخطاء.
الخطأ الثاني يعتمد على ما إذا كانت الإضافات مثبتة. في هذه الحالة، لم أقم بتثبيتها، لذا حصلت على خطأ يتعلق بـ Data Explorer، وهناك هو حيث تبدأ الأمور في التعقد.
في المسؤول > النسخ الاحتياطي > السجلات:
[2019-12-07 07:38:34] CREATE INDEX
[2019-12-07 07:38:34] CREATE INDEX
[2019-12-07 07:38:34] ERROR: تعذر إنشاء فهرس فريد “index_plugin_store_rows_on_plugin_name_and_key”
[2019-12-07 07:38:34] DETAIL: المفتاح (plugin_name, key)=(discourse-data-explorer, q:-6) مكرر.
[2019-12-07 07:38:34] ERROR: تم إلغاء المعاملة الحالية، والأوامر يتم تجاهلها حتى نهاية كتلة المعاملة
[2019-12-07 07:38:34] ERROR: تم إلغاء المعاملة الحالية، والأوامر يتم تجاهلها حتى نهاية كتلة المعاملة
< يتكرر 1000 مرة ثم يتوقف >
والمخرج المقابل في سجل postgres:
2019-12-07 07:38:34.718 UTC [8991] discourse@discourse LOG: المدة: 165.427 مللي ثانية العبارة: CREATE INDEX index_notifications_on_user_
id_and_topic_id_and_post_number ON public.notifications USING btree (user_id, topic_id, post_number);
2019-12-07 07:38:34.767 UTC [8991] discourse@discourse ERROR: تعذر إنشاء فهرس فريد “index_plugin_store_rows_on_plugin_name_an
d_key”
2019-12-07 07:38:34.767 UTC [8991] discourse@discourse DETAIL: المفتاح (plugin_name, key)=(discourse-data-explorer, q:-6) مكرر.
2019-12-07 07:38:34.767 UTC [8991] discourse@discourse STATEMENT: CREATE UNIQUE INDEX index_plugin_store_rows_on_plugin_name_and_key O
N public.plugin_store_rows USING btree (plugin_name, key);
2019-12-07 07:38:34.984 UTC [8991] discourse@discourse ERROR: تم إلغاء المعاملة الحالية، والأوامر يتم تجاهلها حتى نهاية كتلة المعاملة
2019-12-07 07:38:34.984 UTC [8991] discourse@discourse STATEMENT: CREATE INDEX index_policy_users_on_post_policy_id_and_user_id ON pub
lic.policy_users USING btree (post_policy_id, user_id);
في الواقع، توجد استعلامات مكررة مع أزواج مكررة من (plugin_name, key)، مثل q:-11 و q:-2، ولكن مع معرفات فريدة. لا أرى أي نمط بين المكررات، كأنها ليست استعلاماتي المفضلة أو شيء من هذا القبيل.
لذلك، ستكون خطوتي التالية هي إزالة المكررات، عمل نسخة احتياطية، ثم محاولة الاستعادة منها.
لا أستطيع إعادة إنتاج هذه المشكلة على موقع اختبار نظيف، لكنها تحدث باستمرار على موقع الإنتاج. لقد قمت بتثبيت جميع إضافات الإنتاج على موقع الاختبار، ومع ذلك لا يزال لا يمكنني إعادة إنتاج المشكلة.
كيف يمكنني تتبع ما الخطأ في موقع الإنتاج الخاص بي؟
كيف يمكنني إزالة الاستعلامات المكررة، حيث إنها مملوكة للنظام؟ هل عليّ استخدام أمر sudo -u postgres psql discourse...؟ يبدو الأمر مخيفًا.