نظرة عامة على جداول النظام
توفر جداول النظام معلومات حول:
- حالات الخادم وعملياته وبيئته.
- العمليات الداخلية للخادم.
- الخيارات المستخدمة عند بناء الملف التنفيذي لـ ClickHouse.
جداول النظام:
- موجودة في قاعدة البيانات
system.
- متاحة للقراءة فقط.
- لا يمكن إسقاطها أو تعديلها، ولكن يمكن فصلها.
تخزّن معظم جداول النظام بياناتها في RAM. وينشئ ClickHouse server هذه الجداول عند بدء التشغيل.
وعلى عكس جداول النظام الأخرى، فإن جداول سجل النظام metric_log وquery_log وquery_thread_log وtrace_log وpart_log وcrash_log وtext_log وbackup_log تستخدم محرك الجدول MergeTree، وتخزّن بياناتها في filesystem افتراضيًا. وإذا أزلت جدولًا من filesystem، فسيُنشئ ClickHouse server جدولًا فارغًا من جديد عند كتابة البيانات التالية. وإذا تغيّر مخطط جدول نظام في release جديد، فسيُعيد ClickHouse تسمية الجدول الحالي ويُنشئ جدولًا جديدًا.
يمكن تخصيص جداول سجل النظام بإنشاء config file يحمل الاسم نفسه للجدول ضمن /etc/clickhouse-server/config.d/، أو بضبط العناصر المقابلة في /etc/clickhouse-server/config.xml. والعناصر التي يمكن تخصيصها هي:
database: قاعدة البيانات التي ينتمي إليها جدول سجل النظام. هذا الخيار Deprecated الآن. جميع جداول سجل النظام موجودة ضمن قاعدة البيانات system.
table: الجدول الذي تُدرج فيه البيانات.
partition_by: حدّد expression PARTITION BY.
ttl: حدّد expression TTL للجدول.
flush_interval_milliseconds: الفاصل الزمني لتفريغ البيانات إلى disk.
engine: يوفّر expression كاملًا للمحرك (يبدأ بـ ENGINE = ) مع parameters. يتعارض هذا الخيار مع partition_by وttl. وإذا تم تعيينها معًا، فسيقوم server بraise an exception ثم الخروج.
مثال:
<clickhouse>
<query_log>
<database>system</database>
<table>query_log</table>
<partition_by>toYYYYMM(event_date)</partition_by>
<ttl>event_date + INTERVAL 30 DAY DELETE</ttl>
<!--
<engine>ENGINE = MergeTree PARTITION BY toYYYYMM(event_date) ORDER BY (event_date, event_time) SETTINGS index_granularity = 1024</engine>
-->
<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>
<flush_on_crash>false</flush_on_crash>
</query_log>
</clickhouse>
بشكل افتراضي، يكون نمو الجدول غير محدود. للتحكم في حجم الجدول، يمكنك استخدام إعدادات TTL لإزالة سجلات السجل القديمة. كما يمكنك أيضًا استخدام ميزة التقسيم في الجداول التي تستخدم المحرك MergeTree.
لجمع مقاييس النظام، يستخدم ClickHouse server ما يلي:
- القدرة
CAP_NET_ADMIN.
- procfs (في Linux فقط).
procfs
إذا لم تكن لدى ClickHouse server القدرة CAP_NET_ADMIN، فإنه يحاول التبديل تلقائيًا إلى ProcfsMetricsProvider. ويتيح ProcfsMetricsProvider جمع مقاييس النظام لكل استعلام (لـ CPU وI/O).
إذا كان procfs مدعومًا ومُمكّنًا على النظام، فإن ClickHouse server يجمع هذه المقاييس:
OSCPUVirtualTimeMicroseconds
OSCPUWaitMicroseconds
OSIOWaitMicroseconds
OSReadChars
OSWriteChars
OSReadBytes
OSWriteBytes
يكون OSIOWaitMicroseconds معطّلًا افتراضيًا في نوى Linux ابتداءً من الإصدار 5.14.x.
يمكنك تمكينه باستخدام sudo sysctl kernel.task_delayacct=1 أو بإنشاء ملف .conf في /etc/sysctl.d/ يتضمن kernel.task_delayacct = 1
جداول النظام في ClickHouse Cloud
في ClickHouse Cloud، توفّر جداول النظام رؤى بالغة الأهمية حول حالة الخدمة وأدائها، تمامًا كما هو الحال في عمليات النشر ذاتية الإدارة. وتعمل بعض جداول النظام على مستوى العنقود بالكامل، ولا سيما تلك التي تستمد بياناتها من عُقد Keeper التي تدير البيانات الوصفية الموزعة. وتعكس هذه الجداول الحالة العامة للعنقود، ويجب أن تكون متسقة عند الاستعلام عنها من العُقد الفردية. على سبيل المثال، يجب أن يكون جدول parts متسقًا بغض النظر عن العُقدة التي يُجرى منها الاستعلام:
SELECT hostname(), count()
FROM system.parts
WHERE `table` = 'pypi'
┌─hostname()────────────────────┬─count()─┐
│ c-ecru-qn-34-server-vccsrty-0 │ 26 │
└───────────────────────────────┴─────────┘
1 row in set. Elapsed: 0.005 sec.
SELECT
hostname(),
count()
FROM system.parts
WHERE `table` = 'pypi'
┌─hostname()────────────────────┬─count()─┐
│ c-ecru-qn-34-server-w59bfco-0 │ 26 │
└───────────────────────────────┴─────────┘
1 row in set. Elapsed: 0.004 sec.
في المقابل، تكون بعض جداول النظام الأخرى خاصة بكل عقدة، مثل تلك الموجودة في الذاكرة أو التي تحتفظ ببياناتها باستخدام محرك الجدول MergeTree. وهذا شائع في بيانات مثل السجلات والمقاييس. ويضمن هذا التخزين الدائم بقاء البيانات التاريخية متاحة للتحليل. ومع ذلك، فإن هذه الجداول الخاصة بالعقدة تكون، بطبيعتها، فريدة لكل عقدة.
بوجه عام، يمكن تطبيق القواعد التالية عند تحديد ما إذا كان جدول من جداول النظام خاصًا بعقدة معينة:
- جداول النظام التي تحمل اللاحقة
_log.
- جداول النظام التي تعرض المقاييس، مثل
metrics وasynchronous_metrics وevents.
- جداول النظام التي تعرض العمليات الجارية، مثل
processes وmerges.
بالإضافة إلى ذلك، قد تُنشأ إصدارات جديدة من جداول النظام نتيجةً للترقيات أو للتغييرات التي تطرأ على مخططها. وتُسمّى هذه الإصدارات باستخدام لاحقة رقمية.
على سبيل المثال، لنأخذ جداول system.query_log، التي تحتوي على صف لكل query تنفذه العقدة:
SHOW TABLES FROM system LIKE 'query_log%'
┌─name─────────┐
│ query_log │
│ query_log_1 │
│ query_log_10 │
│ query_log_2 │
│ query_log_3 │
│ query_log_4 │
│ query_log_5 │
│ query_log_6 │
│ query_log_7 │
│ query_log_8 │
│ query_log_9 │
└──────────────┘
11 rows in set. Elapsed: 0.004 sec.
يمكننا إجراء استعلام عبر هذه الجداول باستخدام الدالة merge. على سبيل المثال، يحدِّد الاستعلام أدناه أحدث استعلام وُجِّه إلى العقدة المستهدفة في كل جدول query_log:
SELECT
_table,
max(event_time) AS most_recent
FROM merge('system', '^query_log')
GROUP BY _table
ORDER BY most_recent DESC
┌─_table───────┬─────────most_recent─┐
│ query_log │ 2025-04-13 10:59:29 │
│ query_log_1 │ 2025-04-09 12:34:46 │
│ query_log_2 │ 2025-04-09 12:33:45 │
│ query_log_3 │ 2025-04-07 17:10:34 │
│ query_log_5 │ 2025-03-24 09:39:39 │
│ query_log_4 │ 2025-03-24 09:38:58 │
│ query_log_6 │ 2025-03-19 16:07:41 │
│ query_log_7 │ 2025-03-18 17:01:07 │
│ query_log_8 │ 2025-03-18 14:36:07 │
│ query_log_10 │ 2025-03-18 14:01:33 │
│ query_log_9 │ 2025-03-18 14:01:32 │
└──────────────┴─────────────────────┘
11 rows in set. Elapsed: 0.373 sec. Processed 6.44 million rows, 25.77 MB (17.29 million rows/s., 69.17 MB/s.)
Peak memory usage: 28.45 MiB.
لا تعتمد على اللاحقة الرقمية لتحديد الترتيبرغم أن اللاحقة الرقمية في الجداول قد توحي بترتيب البيانات، فلا ينبغي الاعتماد عليها مطلقًا. لذلك، استخدم دائمًا دالة الجدول merge مع عامل تصفية للتاريخ عند الاستعلام عن نطاقات تاريخية محددة.
والأهم من ذلك أن هذه الجداول تظل محلية على مستوى كل عقدة.
للحصول على رؤية شاملة للعنقود بأكمله، يمكن للمستخدمين الاستفادة من الدالة clusterAllReplicas بالاقتران مع الدالة merge. تتيح الدالة clusterAllReplicas الاستعلام عن جداول النظام عبر جميع النسخ المتماثلة داخل العنقود “default”، مع تجميع البيانات الخاصة بكل عقدة في نتيجة موحّدة. وعند دمجها مع الدالة merge، يمكن استخدامها لاستهداف جميع بيانات النظام الخاصة بجدول معيّن داخل عنقود.
تكون هذه المقاربة مفيدة بشكل خاص في مراقبة العمليات على مستوى العنقود واستكشاف أخطائها وإصلاحها، بما يضمن تمكّن المستخدمين من تحليل سلامة نشر ClickHouse Cloud وأدائه بفعالية.
توفّر ClickHouse Cloud عناقيد تضم عدة نسخ متماثلة لتحقيق التكرار والتحويل التلقائي عند التعطل. وهذا يتيح ميزاتها، مثل التحجيم التلقائي الديناميكي والترقيات من دون توقف. وفي لحظة معيّنة، قد تكون هناك عقد جديدة قيد الإضافة إلى العنقود أو الإزالة منه. لتخطي هذه العقد، أضف SETTINGS skip_unavailable_shards = 1 إلى الاستعلامات التي تستخدم clusterAllReplicas كما هو موضح أدناه.
على سبيل المثال، انظر إلى الفرق عند الاستعلام عن جدول query_log — وهو غالبًا ما يكون أساسيًا للتحليل.
SELECT
hostname() AS host,
count()
FROM system.query_log
WHERE (event_time >= '2025-04-01 00:00:00') AND (event_time <= '2025-04-12 00:00:00')
GROUP BY host
┌─host──────────────────────────┬─count()─┐
│ c-ecru-qn-34-server-s5bnysl-0 │ 650543 │
└───────────────────────────────┴─────────┘
1 row in set. Elapsed: 0.010 sec. Processed 17.87 thousand rows, 71.51 KB (1.75 million rows/s., 7.01 MB/s.)
SELECT
hostname() AS host,
count()
FROM clusterAllReplicas('default', system.query_log)
WHERE (event_time >= '2025-04-01 00:00:00') AND (event_time <= '2025-04-12 00:00:00')
GROUP BY host SETTINGS skip_unavailable_shards = 1
┌─host──────────────────────────┬─count()─┐
│ c-ecru-qn-34-server-s5bnysl-0 │ 650543 │
│ c-ecru-qn-34-server-6em4y4t-0 │ 656029 │
│ c-ecru-qn-34-server-iejrkg0-0 │ 641155 │
└───────────────────────────────┴─────────┘
3 rows in set. Elapsed: 0.026 sec. Processed 1.97 million rows, 7.88 MB (75.51 million rows/s., 302.05 MB/s.)
الاستعلام عن عبر العقد والإصدارات
نظرًا لاختلاف إصدارات جداول النظام، فإن هذا لا يزال لا يمثّل كامل البيانات في العنقود. وعند دمج ما سبق مع الدالة merge، نحصل على نتيجة دقيقة لنطاق التاريخ المحدد:
SELECT
hostname() AS host,
count()
FROM clusterAllReplicas('default', merge('system', '^query_log'))
WHERE (event_time >= '2025-04-01 00:00:00') AND (event_time <= '2025-04-12 00:00:00')
GROUP BY host SETTINGS skip_unavailable_shards = 1
┌─host──────────────────────────┬─count()─┐
│ c-ecru-qn-34-server-s5bnysl-0 │ 3008000 │
│ c-ecru-qn-34-server-6em4y4t-0 │ 3659443 │
│ c-ecru-qn-34-server-iejrkg0-0 │ 1078287 │
└───────────────────────────────┴─────────┘
3 rows in set. Elapsed: 0.462 sec. Processed 7.94 million rows, 31.75 MB (17.17 million rows/s., 68.67 MB/s.)