> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Обеспечивает доступ в реальном времени к таблицам базы данных на кластере, указанном в конфигурации сервера, перенаправляя на него запросы `SELECT` и `INSERT`.

# Кластер

Движок баз данных `Cluster` обеспечивает доступ в реальном времени к таблицам базы данных на кластере, указанном в конфигурации сервера. Это аналог движка баз данных [`Remote`](/ru/reference/engines/database-engines/remote) для именованного кластера: соотношение между ними такое же, как между табличными функциями [`cluster`](/ru/reference/functions/table-functions/cluster) и [`remote`](/ru/reference/functions/table-functions/remote).

Список таблиц и их структура запрашиваются у кластера по мере необходимости, поэтому база данных всегда отражает его текущее состояние. Каждая таблица доступна через хранилище на движке [`Distributed`](/ru/reference/engines/table-engines/special/distributed), которое перенаправляет запросы `SELECT` и `INSERT` в именованный кластер.

Это удобно, если нужно объединить несколько кластеров ClickHouse или подключить целый кластер к `clickhouse-local` либо к другому кластеру, не перечисляя его адреса: достаточно один раз задать кластер в конфигурации, указав учётные данные для каждой реплики, параметры защищённых соединений и секрет для межсерверного взаимодействия.

<h2 id="creating-a-database">
  Создание базы данных
</h2>

```sql theme={null}
CREATE DATABASE cluster_db
ENGINE = Cluster('cluster_name', 'database');
```

**Параметры движка**

* `cluster_name` — имя кластера из конфигурации сервера (см. [Кластеры](/ru/reference/engines/table-engines/special/distributed#distributed-clusters)), как в движке таблицы `Distributed`. Поддерживаются [макросы](/ru/reference/settings/server-settings/settings/other#macros), например `{cluster}`: они раскрываются при каждом обращении.
* `database` — имя базы данных в кластере.

В отличие от движка баз данных `Remote`, движок `Cluster` не принимает учётные данные в качестве параметров и не хранит секреты: для соединений используются настройки каждой реплики из конфигурации кластера (пользователь, пароль, защищённые соединения, сжатие и секрет для межсерверного взаимодействия). При каждом обращении кластер заново определяется по конфигурации, поэтому база данных учитывает её повторную загрузку и [автоматическое обнаружение кластеров](/ru/guides/oss/deployment-and-scaling/cluster-discovery), как и таблица `Distributed`. Кластер должен существовать на момент создания базы данных. Если впоследствии он исчезнет из конфигурации, сервер всё равно запустится, но база данных будет сообщать об отсутствии кластера, пока он не появится в конфигурации снова.

Реплика, указывающая на текущий сервер, считается локальным сегментом: `SELECT` и `INSERT` выполняются напрямую от имени текущего пользователя. Поэтому ему нужны соответствующие привилегии на базовую базу данных и её таблицы, а учётные данные из конфигурации кластера используются только для удалённых реплик. Если на локальной реплике сегмента нет базы данных или таблицы, поиск переключается на удалённые реплики этого сегмента, как и в таблице [`Distributed`](/ru/reference/engines/table-engines/special/distributed).

Если в кластере несколько сегментов, каждая прокси-таблица читает данные из всех них, но метаданные — список таблиц и их структуру — получает из одного выбранного сегмента (предпочтение отдаётся локальному). Так же работает табличная функция [`cluster`](/ru/reference/functions/table-functions/cluster): для получения списка достаточно одного запроса вместо отдельного запроса к каждому сегменту. Поэтому предполагается, что во всех сегментах кластера одинаковый набор таблиц. Если таблица есть лишь в некоторых сегментах, прокси-таблица для неё создаётся, но запросы к ней завершаются ошибкой на сегментах, где таблицы нет. При выполнении `INSERT` в таблицу базы данных с несколькими сегментами каждая строка отправляется в случайный сегмент (прокси-таблицы `Distributed` используют неявный ключ сегментирования `rand()` с учётом заданных весов сегментов). Чтобы указать сегмент для запроса, задайте [`insert_shard_id`](/ru/reference/settings/session-settings/insert#insert_shard_id). Неявный ключ используется только для распределения вставляемых строк: при чтении таблица ведёт себя как таблица `Distributed` без ключа сегментирования (в частности, [`optimize_skip_unused_shards`](/ru/reference/settings/session-settings/optimize-skip#optimize_skip_unused_shards) и [`force_optimize_skip_unused_shards`](/ru/reference/settings/session-settings/force-optimize#force_optimize_skip_unused_shards) не используют его для исключения ненужных сегментов).

В частности, таблица, существующая только в сегменте, который не выбран для получения метаданных, не обнаруживается командами `SHOW TABLES` и `EXISTS TABLE`, а при обращении к ней по имени возвращается ошибка `UNKNOWN_TABLE`: прокси-таблицы для запросов к ней нет. Таблица, существующая в выбранном для получения метаданных сегменте, но отсутствующая в другом, видна, однако запросы через прокси могут завершаться ошибкой в том сегменте, где её нет.

Для прокси-таблицы `Cluster` не существует эквивалентного определения, которое можно выполнить повторно, поэтому `SHOW CREATE TABLE` возвращает ошибку `THERE_IS_NO_QUERY`. Это относится к следующим случаям:

* Доступ к таблице сейчас осуществляется через описанное выше переключение на удалённую реплику (на локальной реплике сегмента нет базы данных или таблицы). Таблица `Distributed` для всего кластера не выполняет такого переключения, а используемое при переключении подмножество кластера не имеет собственного имени.
* Имя кластера базы данных содержит макросы. `Cluster` раскрывает их при каждом обращении, а `Distributed` — только при создании таблицы. Поэтому после изменения конфигурации ни выражение с макросом, ни его текущее раскрытое значение не воспроизведут прежнее поведение.
* После повторной загрузки конфигурации кластер с одним сегментом может стать кластером с несколькими сегментами. Тогда действующая прокси-таблица получает неявный ключ `rand()` для распределения вставляемых строк, а в определении таблицы, сохранённом до повторной загрузки, этого ключа нет. Безусловное включение ключа в определение тоже не даёт эквивалентного результата: отдельная таблица `Distributed` использовала бы его для исключения сегментов при чтении, тогда как `CREATE TABLE` не позволяет задать ключ сегментирования только для вставки.

<h2 id="notes">
  Примечания
</h2>

* Движок предоставляет представление кластера только для чтения: `CREATE TABLE`, `DROP TABLE`, `ALTER` и аналогичные DDL-операторы для базы данных `Cluster` не поддерживаются. Управляйте схемой непосредственно в кластере, например с помощью DDL-запросов с предложением [`ON CLUSTER`](/ru/reference/statements/distributed-ddl).
* Права доступа проверяются на удалённых серверах для пользователей, указанных в определении кластера (или для текущего пользователя, если кластер использует секрет для межсерверного взаимодействия), а локально — с учётом обычных привилегий для базы данных и её таблиц.
* Особенности работы движка баз данных `Remote` — правила видимости таблиц локального сегмента, полнота списка таблиц, сообщения об ошибках при недоступности кластера и цепочки прокси-баз данных — также относятся к движку `Cluster`; см. [примечания](/ru/reference/engines/database-engines/remote#notes) к нему.

<h2 id="example">
  Пример
</h2>

Создайте базу данных `Cluster`, которая обращается к базе данных `default` в кластере `test_shard_localhost`, указанном в конфигурации сервера, и используйте её:

```sql theme={null}
CREATE DATABASE cluster_db
ENGINE = Cluster('test_shard_localhost', 'default');
```

```sql theme={null}
SHOW TABLES FROM cluster_db;
```

```text theme={null}
┌─name─┐
│ t    │
└──────┘
```

```sql theme={null}
SELECT * FROM cluster_db.t;
```
