Движок таблицы Buffer
Буферизует данные, подлежащие записи, в оперативной памяти и периодически сбрасывает их в другую таблицу. При чтении данные одновременно считываются из буфера и из другой таблицы.
Рекомендуемая альтернатива движку таблицы Buffer — включение асинхронных вставок.
Параметры движка
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 ГБ.
Пример:
Создание таблицы 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. Это даст скорость всего в несколько тысяч строк в секунду, тогда как вставка больших блоков данных может обеспечить более миллиона строк в секунду.