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

> Буферизует данные в оперативной памяти и периодически сбрасывает их в другую таблицу. При чтении данные одновременно считываются из буфера и из другой таблицы.

# Движок таблицы Buffer

Буферизует данные в оперативной памяти и периодически сбрасывает их в другую таблицу. При чтении данные одновременно считываются из буфера и из другой таблицы.

<Note>
  В качестве рекомендуемой альтернативы движку таблицы Buffer используйте [асинхронные вставки](/ru/concepts/features/operations/insert/asyncinserts).
</Note>

```sql theme={null}
Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes [,flush_time [,flush_rows [,flush_bytes]]])
```

<div id="engine-parameters">
  ### Параметры движка
</div>

<div id="database">
  #### `database`
</div>

`database` — имя базы данных. Можно использовать `currentDatabase()` или другое константное выражение, возвращающее строку.

<div id="table">
  #### `table`
</div>

`table` – Таблица, в которую сбрасываются данные.

<div id="num_layers">
  #### `num_layers`
</div>

`num_layers` — уровень параллелизма. Физически таблица представлена как `num_layers` независимых буферов.

<div id="min_time-max_time-min_rows-max_rows-min_bytes-and-max_bytes">
  #### `min_time`, `max_time`, `min_rows`, `max_rows`, `min_bytes`, and `max_bytes`
</div>

Условия сброса данных из буфера.

<div id="optional-engine-parameters">
  ### Необязательные параметры движка
</div>

<div id="flush_time-flush_rows-and-flush_bytes">
  #### `flush_time`, `flush_rows` и `flush_bytes`
</div>

Условия фонового сброса данных из буфера (если они опущены или равны нулю, параметры `flush*` отсутствуют).

Данные сбрасываются из буфера и записываются в целевую таблицу, если выполнены все условия `min*` или хотя бы одно из условий `max*`.

Кроме того, если выполнено хотя бы одно условие `flush*`, в фоновом режиме запускается сброс. Это отличается от `max*`: `flush*` позволяет отдельно настраивать фоновые сбросы, чтобы не добавлять задержку для запросов `INSERT` к таблицам Buffer.

<div id="min_time-max_time-and-flush_time">
  #### `min_time`, `max_time` и `flush_time`
</div>

Условие для времени в секундах, прошедшего с момента первой записи в буфер.

<div id="min_rows-max_rows-and-flush_rows">
  #### `min_rows`, `max_rows`, and `flush_rows`
</div>

Условие по количеству строк в буфере.

<div id="min_bytes-max_bytes-and-flush_bytes">
  #### `min_bytes`, `max_bytes`, and `flush_bytes`
</div>

Условие по количеству байтов в буфере.

Во время операции записи данные вставляются в один или несколько случайных буферов (настраивается с помощью `num_layers`). Либо, если вставляемая часть данных достаточно велика (больше `max_rows` или `max_bytes`), она записывается непосредственно в целевую таблицу, минуя буфер.

Условия сброса данных вычисляются отдельно для каждого из `num_layers` буферов. Например, если `num_layers = 16` и `max_bytes = 100000000`, максимальное потребление оперативной памяти составляет 1,6 ГБ.

Пример:

```sql theme={null}
CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 1, 10, 100, 10000, 1000000, 10000000, 100000000)
```

Создание таблицы `merge.hits_buffer` с той же структурой, что и у `merge.hits`, с использованием движка Buffer. При записи в эту таблицу данные буферизуются в оперативной памяти, а затем записываются в таблицу 'merge.hits'. Создается один буфер, и данные сбрасываются, если выполняется хотя бы одно из условий:

* прошло 100 секунд с момента последнего сброса (`max_time`) или
* записан 1 миллион строк (`max_rows`) или
* записано 100 МБ данных (`max_bytes`) или
* прошло 10 секунд (`min_time`), и записано 10 000 строк (`min_rows`) и 10 МБ (`min_bytes`) данных

Например, если была записана всего одна строка, то через 100 секунд она будет сброшена в любом случае. Но если записано много строк, данные будут сброшены раньше.

Когда сервер останавливается, при `DROP TABLE` или `DETACH TABLE` буферизованные данные также сбрасываются в целевую таблицу.

Для имени базы данных и таблицы можно указать пустые строки в одинарных кавычках. Это означает отсутствие целевой таблицы. В этом случае при выполнении условий сброса данных буфер просто очищается. Это может быть полезно для хранения окна данных в памяти.

При чтении из таблицы Buffer данные обрабатываются как из буфера, так и из целевой таблицы (если она есть).
Обратите внимание, что таблица Buffer не поддерживает индекс. Иными словами, данные в буфере сканируются полностью, что может быть медленным при больших буферах. (Для данных в подчиненной таблице будет использоваться поддерживаемый ею индекс.)

Если набор столбцов в таблице Buffer не совпадает с набором столбцов в подчиненной таблице, вставляется подмножество столбцов, существующих в обеих таблицах.

Если типы одного из столбцов в таблице Buffer и подчиненной таблице не совпадают, сообщение об ошибке записывается в server log, а буфер очищается.
То же самое происходит, если в момент сброса буфера подчиненная таблица не существует.

<Note>
  Выполнение ALTER для таблицы Buffer в релизах, выпущенных до 26 Oct 2021, вызовет ошибку `Block structure mismatch` (см. [#15117](https://github.com/ClickHouse/ClickHouse/issues/15117) и [#30565](https://github.com/ClickHouse/ClickHouse/pull/30565)), поэтому единственный вариант — удалить таблицу Buffer и затем создать ее заново. Прежде чем пытаться выполнить ALTER для таблицы Buffer, проверьте, исправлена ли эта ошибка в вашей версии.
</Note>

Если сервер аварийно перезапускается, данные в буфере теряются.

`FINAL` и `SAMPLE` не работают корректно для таблиц Buffer. Эти условия передаются в целевую таблицу, но не используются при обработке данных в буфере. Если эти возможности необходимы, мы рекомендуем использовать таблицу Buffer только для записи, а читать из целевой таблицы.

При добавлении данных в таблицу Buffer один из буферов блокируется. Это вызывает задержки, если одновременно с этим из таблицы выполняется операция чтения.

Данные, вставляемые в таблицу Buffer, могут оказаться в подчиненной таблице в другом порядке и в других блоках. Из-за этого таблицу Buffer сложно корректно использовать для записи в CollapsingMergeTree. Чтобы избежать проблем, можно установить `num_layers` в 1.

Если целевая таблица является реплицируемой, при записи в таблицу Buffer теряются некоторые ожидаемые характеристики реплицируемых таблиц. Случайные изменения порядка строк и размеров частей данных приводят к тому, что дедупликация данных перестает работать, а это означает, что надежная запись в реплицируемые таблицы в режиме 'exactly once' невозможна.

Из-за этих недостатков мы можем рекомендовать использование таблицы Buffer только в редких случаях.

Таблица Buffer используется, когда за единицу времени поступает слишком много INSERT от большого числа серверов, и данные нельзя буферизовать до вставки, а значит, INSERT не могут выполняться достаточно быстро.

Обратите внимание, что выполнять вставку данных по одной строке не имеет смысла даже для таблиц Buffer. В этом случае скорость составит всего несколько тысяч строк в секунду, тогда как при вставке более крупных блоков данных она может превышать миллион строк в секунду.
