أوه، فهمت، هذا سيواجه صعوبة مع هذا الاستعلام. بعد التحديث إلى الإصدار الأحدث، هل يمكنك استخراج الاستعلام من mini_profiler وتشغيل explain analyze عليه ومشاركته معنا؟
على Meta (قاعدة بيانات RDS من نوع db.r6g.large بسعة 30 جيجابايت)، يبدو الأمر كالتالي:
تحديث: هذا الالتزام لم يُحدث أي تغيير. لا يزال قاعدة البيانات تعمل بأكثر من 95% بشكل مستمر بعد التحديث، مما يؤدي إلى قتل جميع الاستعلامات القديمة قيد التشغيل. في النسخة التجريبية 4، كانت تعمل بنمط مستقر يتراوح بين 20-30% لهذا المنتدى. لقد قمنا بالفعل بتشغيل عملية تفريغ تلقائي وإعادة فهرسة المخطط.
كيف يمكننا تعطيل هذه الميزة؟ لا يبدو صحيحًا الحصول على مثيل قاعدة بيانات أكبر لحل هذه المشكلة، حيث يبدو أن هناك خطأ في كيفية حساب هذا الاستعلام، خاصةً أنه كان يعمل بشكل ممتاز قبل هذا التحديث.
قمنا بتطبيق رقعة مؤقتة (Monkey-patch) للمشكلة بإعادة توجيه جميع المسارات */private-messages-all/* إلى */private-messages/* فقط بشكل مؤقت. والنتيجة هي أن “جميع الصناديق” يحتوي على نفس محتوى “الشخصي”، لكن على الأقل لا نضطر للتعامل مع استهلاك 100% من وحدة المعالجة المركزية باستمرار بهذه الطريقة.
كود الرقعة المؤقتة:
# name: discourse-private-messages-perf-hotfix
# version: 0.0.1
# authors:
# Prepend to override existing routes
Discourse::Application.routes.prepend do
scope path: nil, constraints: { format: /(json|html|\*\/\*)/ } do
scope "/topics", username: RouteFormat.username do
# Reroute all */private-messages-all/* routes to go to */private-messages/* instead (personal messages)
# Former is expensive, latter is cheap, potentially saves significant database CPU usage
get "private-messages-all/:username" => "list#private_messages", as: "topics_private_messages_override", defaults: { format: :json }
get "private-messages-all-sent/:username" => "list#private_messages_sent", as: "topics_private_messages_sent_override", defaults: { format: :json }
get "private-messages-all-new/:username" => "list#private_messages_new", as: "topics_private_messages_new_override", defaults: { format: :json }
get "private-messages-all-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread_override", defaults: { format: :json }
get "private-messages-all-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive_override", defaults: { format: :json }
end
end
end
استهلاك وحدة المعالجة المركزية لقاعدة بيانات المنتدى بعد نشر الرقعة المؤقتة أعلاه:
@tgxworld ستحتاج إلى إلقاء نظرة أخرى على ما تفعله مسارات */private-messages-all/*، فمن الواضح أن هناك خطأ في طريقة تنفيذها، فهي ليست فعالة بما يكفي لقواعد بيانات المنتديات الكبيرة. إما أن التنفيذ لا يستخدم فهرس قاعدة البيانات الصحيح، أو أن توليد الاستعلامات يؤدي إلى استعلامات باهظة التكلفة للغاية (خاصة على PSQL 10، غير متأكد بشأن 12/13؟).
أدى التنفيذ الحالي إلى شلّ عمل المنتدى تقريبًا، حيث زاد استهلاك وحدة المعالجة المركزية من حوالي 15% إلى 100% بشكل مستمر، مما تسبب في بطء الأداء في جميع ميزات المنتدى الأخرى. لا أرى أي سبب يجعل استعلامات صندوق الوارد الشخصي/المجموعات يستغرق أقل من 50 مللي ثانية بينما يستغرق استعلامات “جميع الصناديق” أكثر من 20 دقيقة لإكمالها.
يمكنك استخدام مُخرجات التحليل (analyze dump) التي نشرها @forkythetoy أعلاه مباشرةً لمشاهدة وقت التنفيذ الذي تجاوز 20 دقيقة سابقًا.
@Falco لقد لاحظت للتو أنك دمجت موضوعنا هنا، لكن يبدو أن هذا يتعلق بنقطة نهاية مختلفة. تقرير الخطأ هذا يتعلق بنقطة نهاية private-message-topic-tracking-state، بينما نحن نتحدث عن */private-messages-all/*. قد يكون هذا هو السبب في بعض الارتباك هنا، وأعتذر عن ذلك. (لقد قمت في البداية بالربط إلى هذا الرابط مما قد يكون سبب الخلط)
إن نقطة نهاية private-message-topic-tracking-state سريعة على منتدانا، لذا فإن هذه ليست المشكلة بالنسبة لنا.
بالنسبة لنا، يستغرق هذا الاستعلام حوالي 200-300 مللي ثانية من وقت قاعدة البيانات. إنه أطول قليلاً مما قد يتوقع المرء، لكنه لا يزال ضمن النطاقات الطبيعية، نعم.
@Hooksmith@forkythetoy هل ستتمكنون من الترقية إلى PG 13؟ هذا هو الحد الأدنى للإصدار الذي يتطلبه Discourse حاليًا. كما أنه من الأصعب بالنسبة لي مقارنة خطط الاستعلام عندما لا يتم تنفيذ الاستعلامات باستخدام نفس إصدار PG.
اضطررت إلى التراجع عن هذا التغيير لأن أداء الاستعلام الجديد يختلف بشكل كبير بين المستخدمين.