Skip to main content

نظرة عامة

تتيح الاستعلامات الخلفية للعملاء إرسال استعلامات تُنفَّذ بشكل مستقل عن جلسة العميل عبر ضبط run_query_in_background=1. وبمجرد الإرسال، يستجيب ClickHouse server فورًا للعميل بينما يواصل الاستعلام تنفيذه حتى الاكتمال (بالنجاح أو بالفشل) على جهة الخادم. وبفصل تنفيذ الاستعلام عن اتصال الشبكة الخاص بالعميل، تصبح المهام الخلفية محصَّنة تمامًا ضد انقطاع اتصال العميل أو أعطال الشبكة العابرة. تستهدف الاستعلامات الخلفية بالدرجة الأولى العمليات طويلة الأمد مثل INSERT ... SELECT، وCREATE TABLE ... AS SELECT، وCREATE MATERIALIZED VIEW ... POPULATE، أو OPTIMIZE TABLE ... FINAL، وهي عمليات يجب ألا تتوقف عند انقطاع اتصال العميل. لا يمكن فصل كل استعلام عن اتصاله. راجع صيغ الاستعلامات غير المدعومة للاطلاع على الطلبات التي تُرفض بدلًا من ذلك.
تُهمَل نتيجة الاستعلام الخلفي، إذ لا يمكن استرجاعها أو الارتباط بها لاحقًا. استخدم query_id الخاص بالاستعلام لمراقبته في system.processes أثناء تشغيله، وفي system.query_log بعد انتهائه.
لا يبقى الاستعلام الخلفي قائمًا بعد إعادة تشغيل الخادم. ويُتحكَّم في سلوك إيقاف الخادم عبر shutdown_wait_unfinished_queries وshutdown_wait_unfinished.

أشكال الاستعلام غير المدعومة

يظل الاستعلام الخلفي قائمًا بعد انتهاء الـ connection الذي أرسله، لذا يجب أن يكون لدى الخادم بالفعل كل ما يلزم لتنفيذ الاستعلام لحظة قبوله. أما الطلبات التي لا تستوفي ذلك فتُرفض بشكل متزامن على الـ connection المُرسِل، ولا يبدأ الاستعلام أصلًا.

البيانات التي تتدفق عبر الاتصال

يُرفض INSERT عندما يظل الخادم بحاجة إلى قراءة البيانات من الاتصال المُرسِل بعد توجيه الاستعلام للتنفيذ. وقد يشمل ذلك كلًا من INSERT ... FORMAT ... والاستعلامات التي تقرأ عبر input. ويُرفض مثل هذا الطلب مع الرسالة A query whose data streams over the connection cannot be run in the background:
يرسل clickhouse-client بيانات INSERT ... FORMAT ... في حزم منفصلة، لذا لا يمكن لهذه الصيغة أن تعمل في الخلفية عبر البروتوكول الأصلي إطلاقًا. أما عبر HTTP، فيمكن قبول أيٍّ من الصيغتين عندما يتّسع الاستعلام الكامل وبياناته في مخزن التحليل الأولي المؤقت، المحدود بقيمة max_query_size. ويشمل ذلك استعلام HTTP الذي يقرأ حمولة مضمّنة عبر input. أما الجسم الأكبر حجمًا فيستمر تدفقه إلى ما بعد نص الاستعلام المخزَّن مؤقتًا، ومن ثمّ يُرفض. لا تعتمد على هذا الحد من الحجم؛ استخدم INSERT ... SELECT أو دالة جدول مثل url أو s3 للبيانات التي يجب تحميلها في الخلفية.

طلبات مرفوضة أخرى

لا يُنقل هذا الإعداد أبدًا إلى الاستعلامات الثانوية لاستعلام موزّع: فعملية INSERT الموزّعة في الخلفية تنفّذ استعلاماتها الخاصة بكل جزء في المقدمة، ضمن الاستعلام الأولي العامل في الخلفية.

إرسال استعلام في الخلفية

بروتوكول TCP الأصلي

عند استخدام clickhouse-client، مرِّر run_query_in_background كإعداد في سطر الأوامر:
يمكنك أيضًا استخدام عبارة SETTINGS مضمّنة:
ينقل البروتوكول الأصلي إعدادات الاستعلام بمعزل عن نص SQL. يحلّل clickhouse-client معظم إعدادات الاستعلام المضمّنة (inline) ويرسلها ضمن قسم الإعدادات هذا. وبدلاً من ذلك، يمكن لمشغّلات البروتوكول الأصلي تمرير run_query_in_background ضمن خريطة الإعدادات الخاصة بكل استعلام، مع إبقاء نص SQL دون تغيير. لا يُرجع البروتوكول الأصلي معرّف query_id مولَّدًا من الخادم، لذا ينبغي على native clients توليد معرّف فريد وإرساله مع الاستعلام. يقوم clickhouse-client --echo-query-id بذلك ويطبع المعرّف قبل إرسال الاستعلام:

بروتوكول HTTP

بالنسبة لطلبات HTTP، مرّر run_query_in_background كمعامل في الـ URL:
تتضمن الاستجابة معرّف الاستعلام المُولَّد في الترويسة X-ClickHouse-Query-Id:
لا يصل ذلك الـ header إلا إلى العميل الذي يقرأ الاستجابة. أما إذا كنت بحاجة إلى handle للاستعلام لا يتوقف على وصول الاستجابة، فأرسل query_id خاصاً بك بوصفه URL parameter. بهذه الطريقة يعرف العميل الـ ID قبل إرسال الطلب، ويمكنه مراقبة الاستعلام أو تنفيذ KILL عليه على العقدة المستقبِلة حتى وإن لم يرَ الاستجابة أبداً:
بخلاف البروتوكول الأصلي (البروتوكول الأصلي)، لا يمكن لـ HTTP تفعيل التنفيذ في الخلفية عبر عبارة SETTINGS مضمّنة في SQL:
يُرجع هذا الطلب استثناء BAD_ARGUMENTS. فمُعالِج HTTP يجب أن يقرر ما إذا كان سينشئ سياق استعلام منفصلًا (detached) قبل تحليل جسم الطلب. مرّر الإعداد في الـ URL، أو هيّئه على مستوى المستخدم أو ملف الإعدادات (profile).

مراقبة التنفيذ

استخدم query_id للتحقق مما إذا كان الاستعلام قيد التنفيذ حالياً:
بعد انتهاء الاستعلام، افحص system.query_log لمعرفة حالته النهائية:
قد ينجح طلب الإرسال حتى لو فشل التنفيذ في الخلفية لاحقًا. في هذه الحالة، يُسجَّل الاستثناء في system.query_log بدلًا من إعادته عبر الاتصال الأصلي.
جداول system.processes وsystem.query_log وأمر KILL QUERY محلية على مستوى العقدة: فكل منها لا يرى سوى استعلامات الخادم الذي يستجيب لها.ينتمي الاستعلام الخلفي إلى الخادم الذي قَبِله، وهو ليس بالضرورة الخادم الذي يصل إليه طلبك التالي عبر موازن الأحمال. لذا اقرأ من العنقود بأكمله بدلًا من ذلك:
ينطبق الأمر نفسه على system.query_log، ويتطلب الإلغاء استخدام الصيغة الشاملة للعنقود:

تأخير flush لـ query log

يتم الاحتفاظ بالـ entries في buffer قبل أن تظهر في system.query_log. في حالة ClickHouse ذاتي الإدارة، يضبط مثال server configuration الخيار query_log.flush_interval_milliseconds على 7500. أما في ClickHouse Cloud، فقد يستغرق ظهور الـ entries ما يصل إلى 30 ثانية. ضع هذا التأخير في الحسبان عند مراقبة queries الخلفية قصيرة التنفيذ. على server ذاتي الإدارة، يمكن للمستخدمين الذين يمتلكون privileges كافية إجبار query log على تنفيذ flush. حدّد اسم الـ log صراحةً حتى لا تتأثر بقية system logs:
تحدث عملية الـ flush على الخادم الذي يتلقّى الـ statement. يتتبّع الاستعلامَ الخلفي الخادمُ الذي قبِله، وليس بالضرورة الخادم المتصلة به جلستك الحالية، لذلك في حالة العنقود نفّذ flush على جميع الخوادم قبل البحث عن الاستعلام:
التفريغ (Flushing) على مستوى العنقود يجعل كل server يكتب الـ entries المخزّنة مؤقتًا لديه فقط، ولا يجعل جدول system.query_log الخاص بـ server آخر مرئيًا محليًا، لذا استمر في قراءة الـ log عبر clusterAllReplicas كما هو موضّح في مراقبة التنفيذ.
آخر تعديل في ٢٦ سبتمبر ٢٠٢٦