ملحق يسبب أخطاء أثناء إعادة البناء

حاولت اليوم ترقية تثبيت Discourse الخاص بي، من 2.9.0.beta9 إلى 2.9.0.beta10. لكن هذا سار بشكل خاطئ للغاية.

  1. كانت محاولتي الأولى على الطرفية
cd /var/discourse
sudo git pull
sudo ./launcher rebuild app

انتهى هذا أخيرًا، مع الرسالة التالية في مكان ما في منتصف جميع السجلات

PG::InvalidParameterValue: ERROR:  cannot extract elements from a scalar
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `exec'

تمكنت من استعادة المنتدى ببساطة عن طريق بدء تشغيل الصورة القديمة (التي كانت لا تزال موجودة).

  1. كانت محاولتي الثانية عبر وحدة تحكم الويب (/admin/upgrade). لكن هذا انتهى أخيرًا بنفس النوع من الخطأ: ERROR: cannot extract elements from a scalar. عند العودة إلى لوحة الترقية، أخبرتني أن جميع المكونات تم تحديثها بشكل جيد. ولكن بعد إعادة تشغيل الحاوية، ألقى الخادم الآن خطأ HTTP 500 :frowning_face:

  2. قمت بتثبيت نظيف على جهاز منفصل، بدءًا من الصفر. تمكنت من تثبيت الإصدار beta10، ولكن محاولة الاستعادة من نسخة احتياطية تسببت في نفس الخطأ بالضبط!

هل هناك أي شخص يمكنه المساعدة؟

لقد وجدت الاستعلام الذي يسبب المشكلة

INSERT INTO question_answer_votes (post_id, user_id, created_at)

	SELECT
	  X.post_id AS post_id,
	  (X.value->>'user_id')::int AS user_id,
	  (X.value->>'created_at')::timestamp AS created_at
	FROM (
	  SELECT
	    post_id,
	    jsonb_array_elements(value::jsonb) AS value
	  FROM post_custom_fields WHERE name = 'vote_history'
	) AS X
	WHERE (X.value->>'action') != 'destroy'
	ORDER BY (X.value->>'created_at')::timestamp DESC
	ON CONFLICT DO NOTHING

إذا فهمت بشكل صحيح، يحدث هذا لأن الدالة jsonb_array_elements في psql تتوقع مصفوفة، ولكنها تتلقى قيمة NULL.

كانت هناك تقارير قليلة عن هذا:

أعتقد أنه قد يكون له علاقة بتثبيت إضافة Pavilion Question/Answer سابقًا؟

سأرى ما إذا كان بإمكاني العثور على شخص ما لإلقاء نظرة أعمق. :+1:

نحن نستخدم هذا المكون الإضافي: https://github.com/angusmcleod/discourse-question-answer.

  • يبدو أنه متعلق بالمكون الإضافي Pavilion Question and Answer.
  • إنه تفرع من المكون الإضافي discourse/discourse-upvotes.
إعجاب واحد (1)

فقط للتحقق، ما هي الإضافات التي لديك في ملف app.yml الخاص بك؟

إعجاب واحد (1)

كان الموقع الذي رأيته يحتوي على الكثير من حقول المنشورات المخصصة التي تحتوي على الكثير من السلاسل النصية التي تم ترميزها عدة مرات بحيث أصبحت غير قابلة للاستخدام.

بعض الحلول، مرتبة حسب التعقيد:

  • التوقف عن استخدام المكون الإضافي (وربما التبديل إلى التصويتات الجديدة)
  • حذفها كلها
  • حذف السيئة منها
  • تحرير تلك الحقول لجعل البيانات مرة أخرى سلاسل JSON صالحة.

الموقع الذي رأيته كان يحتوي على بيانات سيئة قديمة منذ سنوات. يبدو أن هذه مشكلة كانت موجودة منذ سنوات ولم يتم اكتشافها إلا الآن.

قد يكون من الممكن كتابة كود لإصلاح سلاسل JSON المكسورة، لكنني لم أتمكن من رؤية كيفية القيام بذلك في 10 دقائق.

انظر Question Answer Plugin - #301 by pfaffman للحصول على أمثلة.

إعجابَين (2)

لقد فكرت في هذا أيضًا، ولكن بالتحقق السريع من نسخة Angus، لا يبدو أنها أجرت أي عمليات ترحيل للبيانات. https://github.com/angusmcleod/discourse-question-answer/compare/main...discourse:discourse-upvotes:main

هذا يبدو كتلوث للبيانات من مشاركات الأسئلة والأجوبة القديمة كما قلت. أجد أيضًا أنه من المضحك أن هذا يظهر الآن نظرًا لأن هذا الترحيل يعود إلى نوفمبر 2021 - أفترض أن هذا هو السبب في أن JayJay ينتقل فقط إلى المكون الإضافي الجديد الآن؟ على أي حال، سنلقي نظرة على هذا الترحيل مرة أخرى.

إعجاب واحد (1)
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/unfoldingWord-dev/discourse-mermaid.git
          - git clone https://github.com/angusmcleod/discourse-question-answer.git
          - git clone https://github.com/discourse/discourse-checklist.git
          - git clone https://github.com/discourse/discourse-cakeday.git
          - git clone https://github.com/discourse/discourse-canned-replies.git
          - git clone https://github.com/discourse/discourse-footnote.git
          - git clone https://github.com/discourse/discourse-staff-notes.git
          - git clone https://github.com/discourse/discourse-graphviz.git
          - git clone https://github.com/discourse/discourse-assign.git
          - git clone https://github.com/discourse/discourse-voting.git
          - git clone https://github.com/discourse/discourse-yearly-review.git
          - git clone https://github.com/discourse/discourse-saved-searches.git

إعجاب واحد (1)

@nat لن أقوم بالتبديل إلى المكون الإضافي الجديد على الإطلاق. ما زلت أعمل بمجموعة المكونات الإضافية التي لدينا منذ فترة طويلة.

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

إعجابَين (2)

فقط كـ “للعلم” جانبي بسيط بعيدًا عن مشكلة السؤال والجواب، هناك أيضًا بديل للردود الجاهزة الآن:

وأعتقد أن هناك مكون سمة Mermaid رسمي الآن أيضًا:

إعجاب واحد (1)

شكرا لك. سألقي نظرة على ذلك بعد إصلاح مشكلتي الأصلية :ابتسامة:

إعجاب واحد (1)

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

هل قمت بالتعليق على السطر الخاص بالمكوّن الإضافي وحاولت إعادة البناء للتأكد من ذلك؟

إعجابَين (2)

سأجرب ذلك الآن. لقد بحثت في ملف dump.sql، وهو جزء من النسخة الاحتياطية، ولا يوجد أي ذكر لأي جدول question_answer_* على الإطلاق. لذا هذا يعطيني الأمل…

إعجاب واحد (1)

لقد حققت نجاحًا في نظام الاختبار الخاص بي!

  • تم تعطيل المكون الإضافي
  • sudo ./launcher rebuild app
  • استعادة النسخة الاحتياطية

سأعمل على نظامي المباشر. سأبقيك على اطلاع.

إعجاب واحد (1)

البيانات التالفة موجودة في جدول PostCustmField. ولكن إذا لم يكن لديك المكون الإضافي، فلن يحاول ترحيل تلك البيانات إلى الجدول الجديد.

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

إعجابَين (2)

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

كيف يمكنني الاتصال بقاعدة بيانات Discourse بنفسي للتحقق مما هو موجود في جدول post_custom_fields؟

@Jaap-Jan_Swijnenburg أعتذر عن المشكلة التي واجهتها.

سأختلف معك باحترام في ذلك :slight_smile:

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

يمكنك استخدام إضافة مستكشف البيانات للتحقق مما لديك هناك.

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

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

سأفعل ذلك من rails، شيء مثل هذا:

./launcher enter app
rails c

ثم أشياء مثل هذه:

all_votes=PostCustomField.where(name: "vote_history")
likely_broken_votes=PostCustomField.where(name: "vote_history").where("value like '\%"")

انظر فقط إلى المعرف والبيانات:

all_votes.pluck(:id,:value)

احصل على pcf واحد فقط:

pcf=PostCustomField.find(1234)

إصلاحه

pcf.value='the stuff you really want in it'
pcf.save

ما يحدث هنا هو كالتالي:

  1. يمتلك بعض الأشخاص إصدارًا قديمًا جدًا من المكون الإضافي للسؤال والجواب مع اسم مستخدم GitHub الشخصي الخاص بي في عنوان URL للمستودع في ملف app.yml الخاص بهم.

  2. قمت بنقل المكون الإضافي QnA إلى paviliondev منذ سنوات. يقوم GitHub بإعادة توجيه عناوين URL للمستودعات عند نقلها، لذا استمرت عناوين URL القديمة التي تحتوي على اسم المستخدم الشخصي الخاص بي في العمل.

  3. بعد سنوات، نقلت Pavilion المكون الإضافي للسؤال والجواب إلى Discourse. احتفظت Discourse في البداية بالاسم discourse-question-answer.

  4. قبل بضعة أشهر، أنشأت نسخة خاصة بي من المكون الإضافي مستضافة في discourse، بينما كان لا يزال يسمى discourse-question-answer.

  5. الأشخاص الذين لديهم روابط قديمة جدًا للمكون الإضافي QnA مع حساب GitHub الشخصي الخاص بي في عناوين URL الخاصة بهم كانوا يستنسخون الآن نسختي الجديدة من المكون الإضافي المحدث بشكل كبير discourse-question-answer المستضاف في discourse. بمعنى آخر، كان عنوان URL قديم جدًا يشير الآن إلى نسخة من مكون إضافي جديد. على الرغم من السنوات التي مرت، كان ينبغي أن أتوقع ذلك، لذا أعتذر عن ذلك. لقد قمت بإزالة هذه النسخة.

  6. غيرت Discourse اسم discourse-question-answer إلى discourse-upvotes. لم يكن لهذا التغيير في الاسم تأثير مادي على حالتك @Jaap-Jan_Swijnenburg، ولكنه السبب في أنك تقوم الآن (بشكل غير متوقع) باستنساخ نسخة من هذا المستودع.

  7. يفترض الترحيل في discourse/discourse-upvotes (سابقًا discourse-question-answer) أن عمود value في post_custom_fields آمن من حيث النوع كـ JSON.

  8. البيانات القديمة التي تم إنشاؤها بواسطة المكون الإضافي عندما كان angusmcleod/discourse-question-answer (منذ سنوات) لم يتم حفظها كـ JSON صالح بواسطة HasCustomFields في discourse/discourse. أنا أخمن، ولكن ربما تمت إضافة هذه البيانات قبل إضافة التحقق من نوع JSON قبل 4 سنوات (لا يزال من الممكن أن ينتهي بك الأمر بـ JSON غير صالح في الحقول المخصصة المسجلة كـ JSON في حالات الحافة).

لذلك

  1. عندما يقوم الأشخاص الذين لديهم عنوان URL القديم جدًا (angusmcleod/discourse-question-answer) في ملف app.yml الخاص بهم بتحديث Discourse الخاص بهم، يتم استنساخ الترحيل في الإصدار الجديد من المكون الإضافي، ويتم تشغيل الترحيل وربما يؤدي إلى هذا الخطأ.

هناك عدد قليل من الحلول لهذا:

  1. @Jaap-Jan_Swijnenburg في حالتك، تحتاج فقط إلى إزالة الإشارة إلى المكون الإضافي QnA القديم الخاص بي وستتمكن من إعادة بناء موقعك. هذا كل شيء؛ لا شيء أكثر. يبدو أنك فعلت ذلك :+1:

  2. يمكن تحديث ترحيل المكون الإضافي discourse/discourse-upvotes للتعامل مع القيم غير JSON في عمود value في post_custom_fields.

أود أن أشير إلى أن 2 سيتعامل أيضًا مع الحالة الإضافية للأشخاص الذين يرغبون بالفعل في التبديل من إصدار قديم من المكون الإضافي QnA إلى discourse-upvotes. في هذه الحالة، سيتم تشغيل الترحيل وسيفشل إذا كانت أي إدخالات في عمود value في post_custom_fields ليست JSON صالحة.

5 إعجابات