INSERT ... SELECT. Один параметр, deduplicate_insert, управляет синхронными и асинхронными вставками. Для INSERT ... SELECT требуется особое внимание, и у него есть собственный параметр. См. Параметры, управляющие дедупликацией вставок.
Ограничения
Неопределённый статус вставки
Ограничение окна дедупликации
*_deduplication_window других операций вставки, дедупликация может работать не так, как задумано. В этом случае одни и те же данные могут быть вставлены несколько раз.
Настройки, управляющие дедупликацией вставок
- Целевая таблица хранит журнал дедупликации. Это настройка уровня таблицы.
- Для запроса включена дедупликация. Это настройка уровня запроса.
Настройки уровня таблицы
*MergeTree поддерживают дедупликацию при вставке.
Для движков *ReplicatedMergeTree журнал дедупликации включен по умолчанию и управляется настройками replicated_deduplication_window и replicated_deduplication_window_seconds. Для нереплицируемых движков *MergeTree журнал управляется настройкой non_replicated_deduplication_window, которая по умолчанию имеет значение 0. Поэтому обычная таблица MergeTree не выполняет дедупликацию, пока вы не зададите для этого окна положительное значение.
Перечисленные выше настройки определяют параметры журнала дедупликации таблицы. Журнал дедупликации хранит конечное число block_id, которые определяют, как работает дедупликация (см. ниже).
replicated_deduplication_window_for_async_inserts и replicated_deduplication_window_seconds_for_async_inserts — устаревшие настройки. Синхронные и асинхронные вставки теперь используют один журнал дедупликации, поэтому replicated_deduplication_window управляет обеими. Устаревшие настройки ограничивали размер старого каталога ClickHouse Keeper, что важно при поэтапном обновлении.Настройки на уровне запроса
deduplicate_insert принимает три значения:
enable— дедупликация включена для запросаINSERT.disable— дедупликация отключена для запросаINSERT.backward_compatible_choice— решение передаётся устаревшим настройкамinsert_deduplicate(синхронные вставки) иasync_insert_deduplicate(асинхронные вставки).
deduplicate_insert = disable, не записывает block_id для своих блоков. Такие данные нельзя дедуплицировать позднее, даже если повторить вставку с deduplicate_insert = enable. То же относится к случаям, когда целевая таблица не хранит журнал дедупликации: ничего не записывается, поэтому при повторной попытке сопоставить данные будет не с чем.
Старшинство
- Для запроса
INSERT ... SELECTопределяющим является параметрdeduplicate_insert_select. См. Дедупликация для INSERT … SELECT. - Для всех остальных операций
INSERTопределяющим является параметрdeduplicate_insert. - Параметры
insert_deduplicateиasync_insert_deduplicateучитываются только при значенииbackward_compatible_choiceпараметраdeduplicate_insert.
Устаревшие и упразднённые настройки
В версии 26.2 также были изменены значения по умолчанию для
async_insert и deduplicate_blocks_in_dependent_materialized_views: теперь они включены. Настройка compatibility управляет всеми тремя настройками. Если установить для compatibility версию ранее 26.2, эти настройки сохранят прежние значения по умолчанию: для deduplicate_insert будет установлено backward_compatible_choice, и выбор будет передан insert_deduplicate и async_insert_deduplicate. Явно заданная настройка всегда применяется и не зависит от compatibility.
Как работает дедупликация при вставке
*MergeTree, каждому блоку присваивается уникальный block_id — хеш данных в этом блоке. Этот block_id используется как уникальный ключ операции вставки. Если такой же block_id найден в журнале дедупликации, блок считается дубликатом и не вставляется в таблицу.
Этот подход хорошо работает, когда вставки содержат разные данные. Однако если одни и те же данные намеренно вставляются несколько раз, нужно использовать настройку insert_deduplication_token, чтобы управлять процессом дедупликации. Эта настройка позволяет указать уникальный токен для каждой вставки, который ClickHouse использует для определения, являются ли данные дубликатом. insert_deduplication_token имеет более высокий приоритет: если указан токен, ClickHouse не использует хеш-сумму данных.
Для запросов INSERT ... VALUES разбиение вставляемых данных на блоки детерминировано и задаётся настройками. Поэтому повторные попытки вставки следует выполнять с теми же значениями настроек, что и в исходной операции.
Дедупликация для INSERT ... SELECT
INSERT ... SELECT часть SELECT должна при каждой попытке возвращать одни и те же данные в одном и том же порядке. В противном случае блоки и их block_id будут различаться, поэтому повторная попытка не будет распознана как дубликат.
ClickHouse не может проверить, что исходные данные не изменились, но может определить, даёт ли сам запрос воспроизводимый результат. SELECT считается стабильным, если выполняются оба следующих условия:
- Запрос содержит предложение
ORDER BY ALL. Распознаётся только точная конструкцияORDER BY ALL. ОбычныйORDER BY <expressions>не распознаётся, аUNIONиз двух или болееSELECTникогда не считается стабильным. - Конвейер чтения завершается одним потоком.
insert_deduplication_token — равноценная замена стабильности, поскольку в этом случае вставку идентифицирует токен, а не данные.
Настройка deduplicate_insert_select определяет поведение:
enable_when_possible и enable_even_for_bad_queries также учитывают deduplicate_insert: если оно имеет значение disable, запрос не дедуплицируется. force_enable переопределяет deduplicate_insert.
Помните, что выбранная таблица может обновиться между повторными попытками. В этом случае два подхода дают противоположный результат:
- Без
insert_deduplication_tokenзначенияblock_idвычисляются на основе данных. Изменённый результат создаёт другиеblock_id, дедупликация не выполняется, и повторная попытка вставляет новые данные поверх всего, что уже было записано при первой попытке. - С
insert_deduplication_tokenвставку идентифицирует только токен. Повторная попытка распознаётся как дубликат и отбрасывается, даже если она вставила бы другие данные.
Дедупликация асинхронных вставок
async_insert, включенные по умолчанию с версии 26.2) дедуплицируются при повторных попытках так же, как синхронные вставки. Обоими типами управляет параметр deduplicate_insert, поэтому отдельный переключатель не нужен.
Оба типа вставок также используют общий журнал дедупликации и одинаково вычисляют block_id. Поэтому можно переключать клиент между синхронными и асинхронными вставками, не нарушая дедупликацию: повторная попытка, отправленная в одном режиме, всё равно будет распознана как дубликат попытки, отправленной в другом. Перевод рабочей нагрузки с синхронных на асинхронные вставки также безопасен для таблицы, использующей дедупликацию.
До версии 26.2 дедупликация асинхронных вставок по умолчанию была отключена и управлялась параметром
async_insert_deduplicate. Теперь этот параметр учитывается только при значении backward_compatible_choice параметра deduplicate_insert.Гранулярность дедупликации
- Каждый запрос в очереди добавляет в батч один токен дедупликации.
- Токен — это либо значение
insert_deduplication_token, если оно задано в запросе, либо хеш строк, добавленных этим запросом. - Объединение в батчи не влияет на токены, а
insert_deduplication_tokenне влияет на группировку запросов в батчи.
- Если один из запросов в батче является дубликатом, ClickHouse удаляет только строки этого запроса. Остальные данные из батча вставляются как обычно. Часть полностью пропускается только в том случае, если из неё удалены все строки.
- Если два запроса в одном батче имеют одинаковый токен, второй отбрасывается до записи части. Это применяется отдельно для каждой партиции: если два запроса записывают строки в разные партиции, оба сохраняются.
DuplicatedAsyncInserts и SelfDuplicatedAsyncInserts в system.events учитывают эти два случая.
Асинхронные вставки и materialized view
NOT_IMPLEMENTED.
Представление формирует второй блок, когда его результат уже не помещается в один блок. max_block_size задаёт количество строк, помещающихся в блок. Преобразования столбцов, фильтрация и агрегация никогда не добавляют строк, поэтому всегда остаются в одном блоке. JOIN может добавлять строки. Он работает, пока результат не превышает max_block_size, и завершается ошибкой при превышении этого значения.
Чтобы выполнять вставку через представление, формирующее более одного блока, либо установите deduplicate_blocks_in_dependent_materialized_views = 0, либо используйте синхронные вставки.
Дедупликация при вставке с materialized view
replicated_deduplication_windowreplicated_deduplication_window_secondsnon_replicated_deduplication_window
deduplicate_blocks_in_dependent_materialized_views, которая включена по умолчанию начиная с версии 26.2. Для дедупликации должны быть включены оба параметра: deduplicate_insert дедуплицирует данные, вставляемые в исходную таблицу, а deduplicate_blocks_in_dependent_materialized_views дополнительно дедуплицирует данные в зависимых таблицах. Для полной дедупликации включите оба параметра.
При вставке блоков в таблицы materialized view ClickHouse вычисляет block_id, хешируя строку, которая объединяет block_id исходной таблицы и дополнительные идентификаторы. Это обеспечивает точную дедупликацию в materialized view и позволяет различать данные по их исходной вставке независимо от преобразований, применённых до записи в целевую таблицу materialized view.
Примеры
Идентичные блоки после преобразований в materialized view
dst были вставлены две части. 2 блока из select — 2 части при вставке. Эти части содержат разные данные.
mv_dst было вставлено 2 части. Эти части содержат одни и те же данные, однако дедупликация для них не выполнялась.
dst, так и для таблицы mv_dst.
Идентичные блоки при вставке
select получаются два блока — следовательно, для вставки в таблицу dst тоже должно быть два блока. Однако мы видим, что в таблицу dst был вставлен только один блок. Это произошло потому, что для второго блока была выполнена дедупликация. В нём те же данные и тот же ключ дедупликации block_id, который вычисляется как хеш от вставленных данных. Такое поведение не соответствует ожидаемому. Такие случаи редки, но теоретически возможны. Чтобы корректно обрабатывать такие ситуации, пользователь должен указать insert_deduplication_token. Исправим это на следующих примерах:
Идентичные блоки при вставке с insert_deduplication_token
insert_deduplication_token имеет более высокий приоритет: если указан insert_deduplication_token, ClickHouse не использует хеш-сумму данных.
Разные операции вставки после преобразования создают одинаковые данные в базовой таблице materialized view
mv_dst вставляются одни и те же данные. Данные не дедуплицируются, потому что исходные данные различались.
Разные варианты вставки через materialized view в одну базовую таблицу с эквивалентными данными
mv_dst (как и ожидалось).
dst и mv_dst.