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

Движок таблицы 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 и flush_bytes

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

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

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

Пример:

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. Это даст скорость всего в несколько тысяч строк в секунду, тогда как вставка больших блоков данных может обеспечить более миллиона строк в секунду.