INSERT ... SELECT. Uma configuração, deduplicate_insert, controla as inserções síncronas e assíncronas. INSERT ... SELECT exige cuidado adicional e tem sua própria configuração. Consulte Configurações que controlam a desduplicação de inserções.
Limitações
Status incerto da inserção
Limite da janela de desduplicação
*_deduplication_window outras operações de inserção ocorrerem durante a sequência de tentativas, a desduplicação pode não funcionar como esperado. Nesse caso, os mesmos dados podem ser inseridos várias vezes.
Configurações que controlam a desduplicação de inserções
- A tabela de destino mantém um log de desduplicação. Essa é uma configuração no nível da tabela.
- A desduplicação está habilitada para a consulta. Essa é uma configuração no nível da consulta.
Configurações no nível da tabela
*MergeTree oferecem suporte à desduplicação durante a inserção.
Para motores *ReplicatedMergeTree, o log de desduplicação é habilitado por padrão e controlado pelas configurações replicated_deduplication_window e replicated_deduplication_window_seconds. Para motores *MergeTree não replicados, o log é controlado pela configuração non_replicated_deduplication_window, cujo valor padrão é 0. Portanto, uma tabela MergeTree simples não desduplica nada até que você defina essa janela como um valor positivo.
As configurações acima determinam os parâmetros do log de desduplicação de uma tabela. O log de desduplicação armazena um número finito de block_ids, que determinam como a desduplicação funciona (veja abaixo).
replicated_deduplication_window_for_async_inserts e replicated_deduplication_window_seconds_for_async_inserts são configurações legadas. Inserções síncronas e assíncronas agora compartilham um log de desduplicação, portanto replicated_deduplication_window controla ambas. As configurações legadas apenas delimitavam o antigo diretório do ClickHouse Keeper, o que é importante durante um upgrade gradual.Configurações no nível da consulta
deduplicate_insert aceita três valores:
enable— a desduplicação é habilitada para a consultaINSERT.disable— a desduplicação é desabilitada para a consultaINSERT.backward_compatible_choice— a decisão é delegada às configurações legadasinsert_deduplicate(inserções síncronas) easync_insert_deduplicate(inserts assíncronos).
deduplicate_insert = disable não grava block_ids para seus blocos. Esses dados não podem ser desduplicados posteriormente, mesmo que você repita o insert com deduplicate_insert = enable. O mesmo vale quando a tabela de destino não mantém um log de desduplicação: nada é registrado e, portanto, nada pode ser identificado em uma nova tentativa.
Precedência
- Para uma consulta
INSERT ... SELECT, o parâmetrodeduplicate_insert_selecté determinante. Consulte Desduplicação para INSERT … SELECT. - Para todos os outros comandos
INSERT, o parâmetrodeduplicate_inserté determinante. insert_deduplicateeasync_insert_deduplicatesão lidos apenas quandodeduplicate_insertébackward_compatible_choice.
Configurações legadas e obsoletas
A versão 26.2 também alterou os valores padrão de
async_insert e deduplicate_blocks_in_dependent_materialized_views para ativados. A configuração compatibility controla as três. Se você definir compatibility como uma versão anterior à 26.2, essas configurações manterão os valores padrão antigos: deduplicate_insert passa a ser backward_compatible_choice, delegando a decisão a insert_deduplicate e async_insert_deduplicate. Uma configuração definida explicitamente é sempre respeitada e nunca é afetada por compatibility.
Como funciona a desduplicação de inserções
*MergeTree, cada bloco recebe um block_id exclusivo, que é um hash dos dados desse bloco. Esse block_id é usado como chave exclusiva para a operação de inserção. Se o mesmo block_id for encontrado no log de desduplicação, o bloco será considerado duplicado e não será inserido na tabela.
Essa abordagem funciona bem quando as inserções contêm dados diferentes. No entanto, se os mesmos dados forem inseridos intencionalmente várias vezes, você precisará usar a configuração insert_deduplication_token para controlar o processo de desduplicação. Essa configuração permite especificar um token exclusivo para cada inserção, que o ClickHouse usa para determinar se os dados são duplicados. insert_deduplication_token tem prioridade mais alta: o ClickHouse não usa o hash dos dados quando o token é fornecido.
Para consultas INSERT ... VALUES, a divisão dos dados inseridos em blocos é determinística e definida pelas configurações. Portanto, você deve repetir as inserções com os mesmos valores de configuração da operação inicial.
Desduplicação para INSERT ... SELECT
INSERT ... SELECT, a parte SELECT deve retornar os mesmos dados na mesma ordem em todas as tentativas. Caso contrário, os blocos e os block_ids serão diferentes, e a nova tentativa não será reconhecida como duplicada.
O ClickHouse não consegue verificar se os dados de origem não foram alterados, mas pode verificar se a própria consulta produz um resultado reproduzível. Um SELECT é considerado estável quando ambas as condições a seguir são atendidas:
- A consulta contém uma cláusula
ORDER BY ALL. Somente o literalORDER BY ALLé reconhecido. Um simplesORDER BY <expressions>não é reconhecido, e umaUNIONde dois ou maisSELECTs nunca é estável. - O pipeline de leitura termina em um único fluxo.
insert_deduplication_token não vazio é um substituto equivalente para a estabilidade, pois, nesse caso, é o token, e não os dados, que identifica a inserção.
A configuração deduplicate_insert_select define o comportamento:
enable_when_possible e enable_even_for_bad_queries também respeitam deduplicate_insert: se estiver definido como disable, a consulta não será desduplicada. force_enable substitui deduplicate_insert.
Lembre-se de que a tabela selecionada pode ser atualizada entre as tentativas. Os dois caminhos se comportam de maneiras opostas:
- Sem
insert_deduplication_token, osblock_ids são calculados com base nos dados. O resultado alterado produzblock_ids diferentes, a desduplicação não ocorre e a nova tentativa insere os novos dados além de tudo o que a primeira tentativa já gravou. - Com
insert_deduplication_token, apenas o token identifica a inserção. A nova tentativa é reconhecida como duplicada e descartada, mesmo que inserisse dados diferentes.
Desduplicação de inserções assíncronas
async_insert, habilitadas por padrão desde a versão 26.2) são desduplicadas em novas tentativas da mesma forma que as inserções síncronas. deduplicate_insert controla ambos, portanto não é necessário um parâmetro separado.
Os dois tipos de inserção também compartilham um único log de desduplicação e calculam block_ids da mesma forma. Portanto, você pode alternar um cliente entre inserções síncronas e assíncronas sem comprometer a desduplicação, e uma nova tentativa enviada em um modo ainda é reconhecida como duplicata de uma tentativa enviada no outro. Migrar uma carga de trabalho de inserções síncronas para assíncronas continua sendo seguro em uma tabela que depende de desduplicação.
Antes da versão 26.2, a desduplicação de inserções assíncronas era desabilitada por padrão e controlada por
async_insert_deduplicate. Essa configuração agora é lida apenas quando deduplicate_insert é backward_compatible_choice.Granularidade da desduplicação
- Cada consulta na fila contribui com um token de desduplicação para o batch.
- Um token é o valor de
insert_deduplication_token, quando a consulta fornece um, ou um hash das linhas contribuídas por essa consulta. - O agrupamento em batches não influencia os tokens, e
insert_deduplication_tokennão influencia como as consultas são agrupadas em batches.
- Quando uma consulta em um batch é duplicada, o ClickHouse remove apenas as linhas dessa consulta. O restante do batch é inserido normalmente. Uma parte é ignorada por completo somente quando todas as suas linhas são removidas.
- Quando duas consultas no mesmo batch têm o mesmo token, a segunda é descartada antes que a parte seja gravada. Isso se aplica a cada partição: se as duas consultas gravarem linhas em partições diferentes, ambas serão mantidas.
DuplicatedAsyncInserts e SelfDuplicatedAsyncInserts em system.events contabilizam esses dois casos.
Inserções assíncronas e visões materializadas
NOT_IMPLEMENTED.
Uma visão emite um segundo bloco quando sua saída não cabe mais em um único bloco. max_block_size define quantas linhas cabem. Transformações de colunas, filtragem e agregação nunca adicionam linhas, portanto, sempre permanecem em um único bloco. Um JOIN pode adicionar linhas. Ele funciona enquanto o resultado permanecer abaixo de max_block_size e falha acima desse limite.
Para inserir por meio de uma visão que emite mais de um bloco, defina deduplicate_blocks_in_dependent_materialized_views = 0 ou use inserts síncronos.
Desduplicação de inserções com visões materializadas
replicated_deduplication_windowreplicated_deduplication_window_secondsnon_replicated_deduplication_window
deduplicate_blocks_in_dependent_materialized_views, que é habilitada por padrão desde a versão 26.2. Ambas as configurações devem estar habilitadas: deduplicate_insert desduplica os dados inseridos na tabela de origem, e deduplicate_blocks_in_dependent_materialized_views também desduplica os dados nas tabelas dependentes. Habilite ambas se quiser desduplicação completa.
Ao inserir blocos em tabelas sob visões materializadas, o ClickHouse calcula o block_id aplicando hash a uma string que combina os block_ids da tabela de origem com identificadores adicionais. Isso garante uma desduplicação precisa dentro das visões materializadas, permitindo distinguir os dados com base na inserção original, independentemente de quaisquer transformações aplicadas antes de chegarem à tabela de destino sob a visão materializada.
Exemplos
Blocos idênticos após transformações em uma visão materializada
dst. 2 blocos do select — 2 partes ao inserir. As partes contêm dados diferentes.
mv_dst. Essas partes contêm os mesmos dados, no entanto, não são desduplicadas.
dst quanto para mv_dst.
Blocos idênticos durante a inserção
dst. No entanto, vemos que apenas um bloco foi inserido na tabela dst. Isso ocorreu porque o segundo bloco foi desduplicado. Ele tem os mesmos dados e a chave de desduplicação block_id, calculada como um hash dos dados inseridos. Esse comportamento não era o esperado. Casos assim são raros, mas teoricamente podem acontecer. Para lidar corretamente com esses casos, o usuário precisa fornecer um insert_deduplication_token. Vamos corrigir isso com os exemplos a seguir:
Blocos idênticos durante a inserção com insert_deduplication_token
insert_deduplication_token tem prioridade: o ClickHouse não usa o hash dos dados quando insert_deduplication_token é fornecido.
Diferentes operações de inserção produzem os mesmos dados após a transformação na tabela subjacente da visão materializada
mv_dst. Os dados não são desduplicados porque os dados de origem eram diferentes.
Inserções de diferentes visões materializadas em uma única tabela subjacente com dados equivalentes
mv_dst (como esperado).
dst e mv_dst.