الانتقال إلى المحتوى الرئيسي
يشغّل ClickHouse أداة تنميط تعتمد على أخذ العينات تتيح تحليل تنفيذ الاستعلامات. وباستخدام أداة التنميط، يمكنك العثور على إجراءات الشيفرة المصدرية الأكثر استخدامًا أثناء تنفيذ الاستعلام. يمكنك تتبّع وقت CPU والوقت الفعلي المنقضي، بما في ذلك وقت الخمول. يتم تمكين أداة تنميط الاستعلامات تلقائيًا في ClickHouse Cloud. يعثر مثال الاستعلام التالي على تتبعات المكدس الأكثر تكرارًا لاستعلام خضع للتنميط، مع أسماء الدوال بعد حلّ الرموز ومواضعها في الشيفرة المصدرية:
استبدل قيمة query_id بمعرّف الاستعلام الذي تريد تنميطه.
في ClickHouse Cloud، يمكنك الحصول على معرّف الاستعلام بالنقر على ”…” في أقصى يمين الشريط أعلى جدول نتائج الاستعلام (بجوار مفتاح التبديل table/chart). سيؤدي ذلك إلى فتح قائمة سياق يمكنك من خلالها النقر على “Copy query ID”.استخدم clusterAllReplicas(default, system.trace_log) للاختيار من جميع عُقد الـ cluster:
SELECT
    count(),
    arrayStringConcat(arrayMap(x -> concat(demangle(addressToSymbol(x)), '\n    ', addressToLine(x)), trace), '\n') AS sym
FROM clusterAllReplicas(default, system.trace_log)
WHERE query_id = '<query_id>' AND trace_type = 'CPU' AND event_date = today()
GROUP BY trace
ORDER BY count() DESC
LIMIT 10
SETTINGS allow_introspection_functions = 1

استخدام أداة تنميط الاستعلامات في عمليات النشر المُدارة ذاتيًا

في عمليات النشر المُدارة ذاتيًا، لاستخدام أداة تنميط الاستعلامات اتبع الخطوات التالية:
1

ثبّت ClickHouse مع معلومات تصحيح الأخطاء

ثبّت الحزمة clickhouse-common-static-dbg:
  1. اتبع التعليمات في الخطوة “إعداد مستودع Debian”
  2. شغّل sudo apt-get install clickhouse-server clickhouse-client clickhouse-common-static-dbg لتثبيت الملفات الثنائية المترجمة لـ ClickHouse مع معلومات تصحيح الأخطاء
  3. شغّل sudo service clickhouse-server start لبدء تشغيل الخادم
  4. شغّل clickhouse-client. سيلتقط الخادم تلقائيًا رموز تصحيح الأخطاء من clickhouse-common-static-dbg — ولا تحتاج إلى القيام بأي إجراء خاص لتمكينها
2

تحقّق من إعدادات الخادم

تأكد من إعداد قسم trace_log في ملف إعدادات الخادم. وهو مُمكَّن افتراضيًا:
<!-- سجل التتبّع. يخزّن تتبعات المكدس التي تجمعها أدوات تحليل الاستعلامات.
     راجع الإعدادين query_profiler_real_time_period_ns و query_profiler_cpu_time_period_ns. -->
<trace_log>
    <database>system</database>
    <table>trace_log</table>

    <partition_by>toYYYYMM(event_date)</partition_by>
    <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    <max_size_rows>1048576</max_size_rows>
    <reserved_size_rows>8192</reserved_size_rows>
    <buffer_size_rows_flush_threshold>524288</buffer_size_rows_flush_threshold>
    <!-- يحدد ما إذا كان ينبغي تفريغ السجلات إلى القرص عند حدوث crash -->
    <flush_on_crash>false</flush_on_crash>
    <symbolize>true</symbolize>
</trace_log>
يضبط هذا القسم الجدول النظامي trace_log الذي يحتوي على نتائج عمل أداة التحليل. تذكّر أن البيانات في هذا الجدول تكون صالحة فقط أثناء تشغيل الخادم. بعد إعادة تشغيل الخادم، لا ينظّف ClickHouse هذا الجدول، وقد تصبح جميع عناوين الذاكرة الافتراضية المخزنة غير صالحة.
3

اضبط مؤقتات التحليل

أعِد الإعدادين query_profiler_cpu_time_period_ns أو query_profiler_real_time_period_ns. يمكن استخدام كلا الإعدادين في الوقت نفسه.تتيح لك هذه الإعدادات ضبط مؤقتات أداة التحليل. وبما أنها إعدادات جلسة، يمكنك استخدام تردد sampling مختلف للخادم بالكامل، أو للمستخدمين الأفراد أو ملفات تعريف المستخدمين، أو لجلسة العمل التفاعلية الخاصة بك، أو لكل query على حدة.تردد sampling الافتراضي هو عينة واحدة في الثانية، كما أن مؤقتَي CPU والوقت الفعلي مُمكَّنان. ويتيح لك هذا التردد جمع معلومات كافية عن ClickHouse cluster لديك من دون التأثير في أداء الخادم. إذا كنت بحاجة إلى تحليل كل query على حدة، فاستخدم تردد sampling أعلى.
4

حلّل الجدول النظامي trace_log

لتحليل الجدول النظامي trace_log، اسمح باستخدام دوال الاستبطان عبر الإعداد allow_introspection_functions:
SET allow_introspection_functions=1
لدواعٍ أمنية، تكون دوال الاستبطان معطّلة افتراضيًا
استخدم دوال الاستبطان addressToLine وaddressToLineWithInlines وaddressToSymbol وdemangle للحصول على أسماء الدوال ومواضعها في شيفرة ClickHouse. وللحصول على profile لاستعلام معيّن، تحتاج إلى تجميع البيانات من الجدول trace_log. ويمكنك تجميع البيانات بحسب الدوال الفردية أو بحسب تتبعات المكدس كاملة.
إذا كنت بحاجة إلى تصوّر معلومات trace_log، فجرّب flamegraph وspeedscope.

إنشاء مخططات اللهب باستخدام الدالة flameGraph

يوفّر ClickHouse الدالة التجميعية flameGraph التي تُنشئ مخطط اللهب مباشرةً من تتبعات المكدس المخزّنة في trace_log. ويكون الناتج مصفوفة من السلاسل النصية بتنسيق متوافق مع flamegraph.pl. البنية:
flameGraph(traces, [size = 1], [ptr = 0])
الوسائط:
  • traces — تتبّع مكدس الاستدعاءات. Array(UInt64).
  • size — حجم التخصيص لتنميط الذاكرة. Int64.
  • ptr — عنوان التخصيص. UInt64.
عندما تكون قيمة ptr غير صفرية، فإن flameGraph يطابق بين التخصيصات (size > 0) وعمليات إلغاء التخصيص (size < 0) التي لها الحجم والمؤشر نفسيهما. ولا تُعرض إلا التخصيصات التي لم تُحرَّر. وتُتجاهل عمليات إلغاء التخصيص غير المطابقة.

مخطط اللهب للـ CPU

تتطلب الاستعلامات أدناه أن يكون flamegraph.pl مثبّتًا على جهازك.يمكنك القيام بذلك بتشغيل:
git clone https://github.com/brendangregg/FlameGraph
# ثم استخدمه على النحو التالي:
# ~/FlameGraph/flamegraph.pl
استبدل flamegraph.pl في الاستعلامات التالية بالمسار الذي يوجد فيه flamegraph.pl على جهازك.
SET query_profiler_cpu_time_period_ns = 10000000;
نفّذ الاستعلام، ثم أنشئ مخطط اللهب:
clickhouse client --allow_introspection_functions=1 \
    -q "SELECT arrayJoin(flameGraph(arrayReverse(trace)))
        FROM system.trace_log
        WHERE trace_type = 'CPU' AND query_id = '<query_id>'" \
    | flamegraph.pl > flame_cpu.svg

مخطط اللهب للذاكرة — جميع عمليات تخصيص الذاكرة

SET memory_profiler_sample_probability = 1, max_untracked_memory = 1;
شغّل استعلامك، ثم أنشئ مخطط اللهب:
clickhouse client --allow_introspection_functions=1 \
    -q "SELECT arrayJoin(flameGraph(trace, size))
        FROM system.trace_log
        WHERE trace_type = 'MemorySample' AND query_id = '<query_id>'" \
    | flamegraph.pl --countname=bytes --color=mem > flame_mem.svg

مخطط اللهب للذاكرة — التخصيصات غير المُحرَّرة

يطابق هذا النمط عمليات التخصيص مع عمليات تحرير الذاكرة بحسب المؤشر، ويعرض فقط الذاكرة التي لم تُحرَّر أثناء الاستعلام.
SET memory_profiler_sample_probability = 1, max_untracked_memory = 1,
    use_uncompressed_cache = 1,
    merge_tree_max_rows_to_use_cache = 100000000000,
    merge_tree_max_bytes_to_use_cache = 1000000000000;
نفّذ الاستعلام التالي لإنشاء مخطط اللهب:
clickhouse client --allow_introspection_functions=1 \
    -q "SELECT arrayJoin(flameGraph(trace, size, ptr))
        FROM system.trace_log
        WHERE trace_type = 'MemorySample' AND query_id = '<query_id>'" \
    | flamegraph.pl --countname=bytes --color=mem > flame_mem_unfreed.svg

مخطط اللهب للذاكرة — التخصيصات النشطة في لحظة زمنية معيّنة

يتيح لك هذا الأسلوب تحديد ذروة استخدام الذاكرة وتصور ما كان مخصصًا في تلك اللحظة.
SET memory_profiler_sample_probability = 1, max_untracked_memory = 1;

تتبّع استخدام الذاكرة بمرور الوقت

SELECT
    event_time,
    formatReadableSize(max(s)) AS m
FROM (
    SELECT
        event_time,
        sum(size) OVER (ORDER BY event_time) AS s
    FROM system.trace_log
    WHERE query_id = '<query_id>' AND trace_type = 'MemorySample'
)
GROUP BY event_time
ORDER BY event_time;

حدِّد النقطة الزمنية ذات أعلى استخدام للذاكرة

SELECT
    argMax(event_time, s),
    max(s)
FROM (
    SELECT
        event_time,
        sum(size) OVER (ORDER BY event_time) AS s
    FROM system.trace_log
    WHERE query_id = '<query_id>' AND trace_type = 'MemorySample'
);

أنشئ مخطط اللهب لتخصيصات الذاكرة النشطة عند تلك اللحظة الزمنية

clickhouse client --allow_introspection_functions=1 \
    -q "SELECT arrayJoin(flameGraph(trace, size, ptr))
        FROM (
            SELECT * FROM system.trace_log
            WHERE trace_type = 'MemorySample'
              AND query_id = '<query_id>'
              AND event_time <= '<time_point>'
            ORDER BY event_time
        )" \
    | flamegraph.pl --countname=bytes --color=mem > flame_mem_time_point_pos.svg

أنشئ مخطط مخطط اللهب لعمليات تحرير الذاكرة بعد تلك النقطة الزمنية (لفهم ما الذي حُرِّر لاحقًا)

clickhouse client --allow_introspection_functions=1 \
    -q "SELECT arrayJoin(flameGraph(trace, -size, ptr))
        FROM (
            SELECT * FROM system.trace_log
            WHERE trace_type = 'MemorySample'
              AND query_id = '<query_id>'
              AND event_time > '<time_point>'
            ORDER BY event_time DESC
        )" \
    | flamegraph.pl --countname=bytes --color=mem > flame_mem_time_point_neg.svg

مثال

مقتطف الشيفرة أدناه:
  • يطبّق عامل تصفية على بيانات trace_log حسب معرّف الاستعلام والتاريخ الحالي.
  • يجمّع حسب تتبّع المكدس.
  • يستخدم دوال الاستبطان للحصول على تقرير يتضمن:
    • أسماء الرموز والدوال المقابلة لها في الشيفرة المصدرية.
    • مواضع هذه الدوال في الشيفرة المصدرية.
SELECT
    count(),
    arrayStringConcat(arrayMap(x -> concat(demangle(addressToSymbol(x)), '\n    ', addressToLine(x)), trace), '\n') AS sym
FROM system.trace_log
WHERE (query_id = '<query_id>') AND (event_date = today())
GROUP BY trace
ORDER BY count() DESC
LIMIT 10
آخر تعديل في ٢٩ يونيو ٢٠٢٦