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

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

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

Примечание

Рекомендуемая альтернатива движку таблицы Buffer — включение асинхронных вставок.

Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes [,flush_time [,flush_rows [,flush_bytes]]])

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

database

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

table

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

num_layers

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

min_time, max_time, min_rows, max_rows, min_bytes и max_bytes

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

Необязательные параметры движка

flush_time, flush_rows и flush_bytes

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

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

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

min_time, max_time и flush_time

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

min_rows, max_rows и flush_rows

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

min_bytes, max_bytes, and flush_bytes

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

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

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

Пример:

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 и подчинённой таблице, в журнал сервера записывается сообщение об ошибке и буфер очищается. То же самое происходит, если подчинённая таблица не существует в момент сброса буфера.

Примечание

Выполнение ALTER для таблицы Buffer в релизах, выпущенных до 26 октября 2021 года, приведёт к ошибке Block structure mismatch (см. #15117 и #30565), поэтому единственный вариант — удалить таблицу Buffer и затем создать её заново. Перед тем как выполнять ALTER для таблицы Buffer, проверьте, что эта ошибка исправлена в вашем релизе.

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

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

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

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

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

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

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

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