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

> Ограничения для настроек можно задать в разделе `profiles` файла конфигурации `user.xml`; они запрещают пользователям изменять некоторые настройки с помощью запроса `SET`.

# Ограничения для настроек

<h2 id="overview">
  Обзор
</h2>

В ClickHouse «ограничения» для настроек — это ограничения и правила,
которые можно назначать настройкам. Эти ограничения помогают поддерживать
стабильность, безопасность и предсказуемое поведение вашей базы данных.

<h2 id="defining-constraints">
  Определение ограничений
</h2>

Ограничения для настроек можно задать в разделе `profiles` файла конфигурации `user.xml`.
Они запрещают пользователям изменять некоторые настройки с помощью оператора
[`SET`](/ru/reference/statements/set).

Ограничения задаются следующим образом:

```xml theme={null}
<profiles>
  <user_name>
    <constraints>
      <setting_name_1>
        <min>lower_boundary</min>
      </setting_name_1>
      <setting_name_2>
        <max>upper_boundary</max>
      </setting_name_2>
      <setting_name_3>
        <min>lower_boundary</min>
        <max>upper_boundary</max>
      </setting_name_3>
      <setting_name_4>
        <readonly/>
      </setting_name_4>
      <setting_name_5>
        <min>lower_boundary</min>
        <max>upper_boundary</max>
        <changeable_in_readonly/>
      </setting_name_5>
      <setting_name_6>
        <min>lower_boundary</min>
        <max>upper_boundary</max>
        <disallowed>value1</disallowed>
        <disallowed>value2</disallowed>
        <disallowed>value3</disallowed>
        <changeable_in_readonly/>
      </setting_name_6>
    </constraints>
  </user_name>
</profiles>
```

Если пользователь пытается нарушить ограничения, генерируется исключение, а
значение настройки остается неизменным.

<h2 id="types-of-constraints">
  Типы ограничений
</h2>

В ClickHouse поддерживается несколько типов ограничений:

* `min`
* `max`
* `disallowed`
* `readonly` (с псевдонимом `const`)
* `changeable_in_readonly`

Ограничения `min` и `max` задают верхнюю и нижнюю границы для числовой
настройки и могут использоваться совместно.

Ограничение `disallowed` используется, чтобы указать конкретное значение или набор значений,
которые не допускаются для определенной настройки.

Ограничение `readonly` или `const` указывает, что пользователь вообще не может изменять
соответствующую настройку.

Тип ограничения `changeable_in_readonly` позволяет пользователям изменять настройку
в пределах диапазона `min`/`max`, даже если для настройки `readonly` установлено значение `1`;
в противном случае в режиме `readonly=1` изменять настройки нельзя.

<Note>
  `changeable_in_readonly` поддерживается, только если включен параметр `settings_constraints_replace_previous`:

  ```xml theme={null}
  <access_control_improvements>
    <settings_constraints_replace_previous>true</settings_constraints_replace_previous>
  </access_control_improvements>
  ```
</Note>

<h3 id="readonly-changeable-in-readonly">
  Не делайте `readonly` изменяемым в режиме только для чтения
</h3>

<Warning>
  Не включайте `readonly` в список `changeable_in_readonly` ни в одном профиле, в том числе в профилях, которые никому не назначены: любой сеанс может выбрать профиль по имени.
</Warning>

Не помечайте сам параметр `readonly` как `changeable_in_readonly`. Иначе сеанс, начавшийся со значением `readonly = 1`, сможет выполнить `SET readonly = 0` и вновь получить возможность выполнять запросы на запись, которые и так разрешены его текущими привилегиями, если только то же ограничение не запрещает значение `0`.

Это касается каждого определённого вами профиля, а не только назначенных:

* `SET profile` не проверяется по правам доступа, поэтому любой сеанс может выбрать любой профиль по имени. Профиль остаётся доступным, даже если он никому не назначен, однако вносимые им изменения всё равно проверяются на соответствие ограничениям, уже действующим в этом сеансе.
* По HTTP запросы `GET` принудительно переводятся в `readonly = 2` только тогда, когда эффективное значение в противном случае было бы равно `0`. Поэтому профиль, который задаёт `readonly = 1`, но при этом разрешает изменять `readonly` в режиме только для чтения, сводит эту защиту на нет, поскольку запрос `GET` может переключить значение на `0` и выполнить запись.

<h2 id="multiple-constraint-profiles">
  Несколько профилей ограничений
</h2>

Если для пользователя активно несколько профилей, ограничения объединяются.
Процесс объединения зависит от `settings_constraints_replace_previous`:

* **true** (рекомендуется): ограничения для одной и той же настройки при
  объединении заменяются, поэтому используется последнее ограничение, а все предыдущие игнорируются.
  Это относится и к полям, не заданным в новом ограничении.
* **false** (по умолчанию): ограничения для одной и той же настройки объединяются так,
  что каждый незаданный тип ограничения берётся из предыдущего профиля, а каждый
  заданный тип ограничения заменяется значением из нового профиля.

<h2 id="read-only">
  Режим только для чтения
</h2>

Режим только для чтения включается настройкой `readonly`, которую не следует путать с типом ограничения (CONSTRAINT)
`readonly`. При `readonly = 1` настройку, изменение которой иначе было бы отклонено, всё же можно изменить,
если это допускает ограничение `changeable_in_readonly`. О том, что означают значения этой настройки, см.
[справочник по настройкам](/ru/reference/settings/session-settings/other#readonly); о том, какие классы запросов
разрешает каждое значение и как его устанавливает HTTP interface, см.
[разрешения для запросов](/ru/concepts/features/configuration/settings/permissions-for-queries#readonly).

<h3 id="example-read-only">
  Пример
</h3>

Пусть файл `users.xml` содержит следующие строки:

```xml theme={null}
<profiles>
  <default>
    <max_memory_usage>10000000000</max_memory_usage>
    <force_index_by_date>0</force_index_by_date>
    ...
    <constraints>
      <max_memory_usage>
        <min>5000000000</min>
        <max>20000000000</max>
      </max_memory_usage>
      <force_index_by_date>
        <readonly/>
      </force_index_by_date>
    </constraints>
  </default>
</profiles>
```

Для всех следующих запросов будет сгенерировано исключение:

```sql theme={null}
SET max_memory_usage=20000000001;
SET max_memory_usage=4999999999;
SET force_index_by_date=1;
```

```text theme={null}
Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be greater than 20000000000.
Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be less than 5000000000.
Code: 452, e.displayText() = DB::Exception: Setting force_index_by_date should not be changed.
```

<Note>
  Профиль `default` обрабатывается особым образом: все ограничения, заданные для
  профиля `default`, становятся ограничениями по умолчанию, поэтому они применяются ко всем пользователям,
  пока для них явно не заданы другие.
</Note>

<h2 id="constraints-on-merge-tree-settings">
  Ограничения на настройки MergeTree
</h2>

Для [настроек MergeTree](/ru/reference/settings/merge-tree-settings) можно задавать ограничения.
Эти ограничения применяются при создании таблицы с движком MergeTree
или при изменении её настроек хранения.

При указании имени настройки MergeTree в разделе `<constraints>` к нему
необходимо добавлять префикс `merge_tree_`.

<h3 id="example-mergetree">
  Пример
</h3>

Вы можете запретить создание новых таблиц с явно заданной `storage_policy`

```xml theme={null}
<profiles>
  <default>
    <constraints>
      <merge_tree_storage_policy>
        <const/>
      </merge_tree_storage_policy>
    </constraints>
  </default>
</profiles>
```
