Перейти к основному содержанию

Обзор системных таблиц

Системные таблицы предоставляют информацию о:
  • Состоянии сервера, процессах и окружении.
  • Внутренних процессах сервера.
  • Параметрах, использованных при сборке бинарного файла ClickHouse.
Системные таблицы:
  • Находятся в базе данных system.
  • Доступны только для чтения данных.
  • Не могут быть удалены или изменены, но могут быть отсоединены.
Большинство системных таблиц хранят свои данные в оперативной памяти. Сервер ClickHouse создает такие системные таблицы при запуске. В отличие от других системных таблиц, системные таблицы логов metric_log, query_log, query_thread_log, trace_log, part_log, crash_log, text_log и backup_log используют движок таблицы MergeTree и по умолчанию хранят свои данные в файловой системе. Если удалить таблицу из файловой системы, сервер ClickHouse при следующей записи данных снова создаст пустую таблицу. Если в новой версии изменилась схема системной таблицы, ClickHouse переименует текущую таблицу и создаст новую. Системные таблицы логов можно настроить, создав файл конфигурации с тем же именем, что и у таблицы, в каталоге /etc/clickhouse-server/config.d/, либо задав соответствующие элементы в /etc/clickhouse-server/config.xml. Можно настраивать следующие элементы:
  • database: база данных, к которой относится системная таблица логов. Этот параметр теперь помечен как устаревший. Все системные таблицы логов находятся в базе данных system.
  • table: таблица для вставки данных.
  • partition_by: задает выражение PARTITION BY.
  • ttl: задает выражение TTL для таблицы.
  • flush_interval_milliseconds: интервал сброса данных на диск.
  • engine: задает полное выражение движка (начиная с ENGINE =) с параметрами. Этот параметр конфликтует с partition_by и ttl. Если задать их вместе, сервер вызовет исключение и завершит работу.
Пример:
<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 использует:
  • capability CAP_NET_ADMIN.
  • procfs (только в Linux).
procfs Если у сервера ClickHouse нет capability CAP_NET_ADMIN, он пытается использовать ProcfsMetricsProvider в качестве резервного варианта. ProcfsMetricsProvider позволяет собирать системные метрики для каждого запроса (для CPU и I/O). Если procfs поддерживается и включен в системе, сервер ClickHouse собирает следующие метрики:
  • 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-026
└───────────────────────────────┴─────────┘

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-026
└───────────────────────────────┴─────────┘

1 row in set. Elapsed: 0.004 sec.
Напротив, другие системные таблицы привязаны к конкретному узлу, например если они хранятся в памяти или сохраняют свои данные с использованием движка таблицы MergeTree. Это типично для таких данных, как журналы и метрики. Такое хранение обеспечивает доступность исторических данных для анализа. Однако эти таблицы, привязанные к узлу, по своей природе уникальны для каждого узла. В общем случае при определении того, привязана ли системная таблица к узлу, можно применять следующие правила:
  • Системные таблицы с суффиксом _log.
  • Системные таблицы, содержащие метрики, например metrics, asynchronous_metrics, events.
  • Системные таблицы, содержащие сведения о текущих процессах, например processes, merges.
Кроме того, новые версии системных таблиц могут создаваться в результате обновлений или изменений их схемы. Эти версии именуются с помощью числового суффикса. Например, рассмотрим таблицы system.query_log, которые содержат строку для каждого запроса, выполненного на данном узле:
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-0650543
└───────────────────────────────┴─────────┘

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-0650543
│ c-ecru-qn-34-server-6em4y4t-0656029
│ c-ecru-qn-34-server-iejrkg0-0641155
└───────────────────────────────┴─────────┘

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-03008000
│ c-ecru-qn-34-server-6em4y4t-03659443
│ c-ecru-qn-34-server-iejrkg0-01078287
└───────────────────────────────┴─────────┘

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.)
Последнее изменение 10 июня 2026 г.