Движок таблицы Буфер
Буферизует данные для записи в ОЗУ, периодически записывая их в другую таблицу. Во время операции чтения данные считываются как из буфера, так и из другой таблицы одновременно.
Рекомендуемая альтернатива движку таблицы Буфер - включение асинхронных вставок.
Параметры движка:
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
Условия для сброса данных из буфера в фоновом режиме (опущенные или нулевые значения означают отсутствие параметров flush*
).
Данные сбрасываются из буфера и записываются в целевую таблицу, если выполняются все условия min*
или хотя бы одно из условий max*
.
Также, если выполняется хотя бы одно условие flush*
, сброс инициируется в фоновом режиме. Это отличается от max*
, поскольку flush*
позволяет конфигурировать фоновые сбросы отдельно, чтобы избежать добавления задержки для запросов INSERT
в таблицы Буфер.
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
, с использованием движка Буфер. При записи в эту таблицу данные буферизуются в ОЗУ и позже записываются в таблицу '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
, буферизованные данные также сбрасываются в целевую таблицу.
Вы можете установить пустые строки в одинарные кавычки для имени базы данных и таблицы. Это указывает на отсутствие целевой таблицы. В этом случае, когда достигаются условия сброса данных, буфер просто очищается. Это может быть полезно для сохранения окна данных в памяти.
При чтении из таблицы Буфер данные обрабатываются как из буфера, так и из целевой таблицы (если таковая имеется). Обратите внимание, что таблица Буфер не поддерживает индекс. Иными словами, данные в буфере полностью сканируются, что может быть медленно для больших буферов. (Для данных в подчиненной таблице будет использоваться индекс, который она поддерживает.)
Если набор колонок в таблице Буфер не совпадает с набором колонок в подчиненной таблице, подмножество колонок, существующих в обеих таблицах, будет вставлено.
Если типы не совпадают для одной из колонок в таблице Буфер и подчиненной таблице, в журнале сервера будет записано сообщение об ошибке, и буфер будет очищен. То же самое происходит, если подчиненная таблица не существует, когда буфер сбрасывается.
Запуск ALTER на таблице Буфер в версиях, выпущенных до 26 октября 2021 года, вызовет ошибку Block structure mismatch
(см. #15117 и #30565), поэтому единственным вариантом является удаление таблицы Буфер и ее повторное создание. Убедитесь, что эта ошибка исправлена в вашей версии, прежде чем пытаться выполнить ALTER на таблице Буфер.
Если сервер перезапускается ненормально, данные в буфере теряются.
FINAL
и SAMPLE
работают некорректно для таблиц Буфер. Эти условия передаются в целевую таблицу, но не используются для обработки данных в буфере. Если эти функции необходимы, мы рекомендуем использовать таблицу Буфер только для записи, в то время как чтение осуществляется из целевой таблицы.
При добавлении данных в таблицу Буфер один из буферов блокируется. Это вызывает задержки, если одновременно выполняется операция чтения из таблицы.
Данные, которые вставляются в таблицу Буфер, могут оказаться в подчиненной таблице в другом порядке и в разных блоках. Из-за этого таблицу Буфер сложно использовать для корректной записи в CollapsingMergeTree. Чтобы избежать проблем, вы можете установить num_layers
в 1.
Если целевая таблица реплицирована, некоторые ожидаемые характеристики реплицируемых таблиц теряются при записи в таблицу Буфер. Случайные изменения порядка строк и размеров частей данных приводят к тому, что дедупликация данных перестает работать, что означает, что невозможно достичь надежной записи 'exactly once' в реплицированные таблицы.
Из-за этих недостатков мы можем рекомендовать использовать таблицу Буфер только в редких случаях.
Таблица Буфер используется, когда получается слишком много INSERT'ов с большого количества серверов за единицу времени, и данные не могут быть буферизированы перед вставкой, что означает, что INSERT'ы не могут выполняться достаточно быстро.
Обратите внимание, что нет смысла вставлять данные по одной строке, даже для таблиц Буфер. Это даст скорость всего в несколько тысяч строк в секунду, в то время как вставка более крупных блоков данных может позволить достичь более миллиона строк в секунду.