Volver al inicio

ClickHouse: desduplicación y pérdidas en MV

El artículo analiza el mecanismo de pérdidas de datos en ClickHouse al usar vistas materializadas debido a la desduplicación de bloques. Describe las condiciones de atomicidad de INSERT, el rol de block_id y las configuraciones recomendadas para eliminar el problema. Adecuado para desarrolladores middle/senior de sistemas OLAP.

Cómo ClickHouse pierde datos en vistas materializadas
Advertisement 728x90

Pérdida de datos en ClickHouse: Desduplicación y vistas materializadas

En ClickHouse, al usar vistas materializadas, los datos en la tabla de destino pueden no coincidir con los de la fuente. Esto ocurre debido a la desduplicación de bloques durante INSERT, especialmente en clústeres replicados. La configuración predeterminada hace que los bloques se ignoren en inserciones repetidas, rompiendo las expectativas de un almacenamiento solo de apéndice. La solución es ajustar los parámetros insert_deduplicate y deduplicate_blocks_in_dependent_materialized_views.

Considera un pipeline típico:

CREATE TABLE source_table (
    message     String
) engine=MergeTree()
ORDER BY (message);

CREATE TABLE final_table (
    message     String
) engine=MergeTree()
ORDER BY (message);

CREATE MATERIALIZED VIEW mv_source_table TO final_table AS
SELECT 
    message
FROM source_table;

Los datos de source_table se copian a final_table, pero con el tiempo, los registros desaparecen de final_table sin ninguna razón aparente.

Google AdInline article slot

Atomicidad de INSERT en detalle

ClickHouse divide los datos de INSERT en bloques según el parámetro max_insert_block_size. La atomicidad solo se garantiza para un único bloque en una partición de tabla MergeTree. Si un INSERT se interrumpe, ClickHouse intenta reintentar la inserción de los bloques faltantes sin notificar al usuario.

En el reintento, entra en acción la desduplicación: cada bloque recibe un block_id como hash de su contenido. Si ese block_id ya está en el registro de desduplicación, se omite todo el bloque. Como resultado:

  • Parte de los datos del INSERT original se pierden.
  • La vista materializada no recibe los datos completos.

Condiciones para la atomicidad:

Google AdInline article slot
  • Inserción en una única partición.
  • Sin INSERT concurrentes en la misma partición.
  • Datos empaquetados en un único bloque.

Si no se cumplen estas condiciones, se producen inserciones parciales y desduplicación en el reintento.

Mecanismo de desduplicación de bloques

La desduplicación opera a nivel de bloque en tablas MergeTree replicadas. El parámetro insert_deduplicate (1 por defecto) habilita las comprobaciones de block_id. Si se encuentra un duplicado, se ignora el bloque.

En tablas no replicadas, la desduplicación está desactivada (non_replicated_deduplication_window=0). Para replicación, se recomienda establecer:

Google AdInline article slot
insert_deduplicate = 0

Esto evita la pérdida de bloques en INSERT repetidos, pero permite duplicados. Para cargas de trabajo analíticas solo de apéndice, los duplicados son aceptables y se limpian durante las fusiones.

Desduplicación en vistas materializadas

Las vistas materializadas realizan INSERT en la tabla de destino basados en los datos fuente. Por defecto, se verifica la desduplicación en la tabla fuente, y el estado se propaga a la vista.

El parámetro deduplicate_blocks_in_dependent_materialized_views controla esto:

  • 0 (predeterminado): Desduplicación en source_table, riesgo de pérdida de datos.
  • 1: Desduplicación en final_table, bloques insertados completamente.

Establece:

SET deduplicate_blocks_in_dependent_materialized_views = 1;

La documentación de ClickHouse advierte explícitamente que sin ajustes, las vistas materializadas pueden perder datos en inserciones repetidas de bloques.

Configuraciones recomendadas

Para eliminar la pérdida de datos, aplica estos cambios en la configuración del servidor o de la sesión:

  • insert_deduplicate = 0 — desactiva la desduplicación en INSERT repetidos.
  • deduplicate_blocks_in_dependent_materialized_views = 1 — desduplicación en MV en la tabla destino.
  • Verifica max_insert_block_size: valores mayores minimizan la división de bloques.
  • Evita INSERT concurrentes en la misma partición.

Monitorea los registros en busca de inserciones parciales y compara COUNT(*) entre las tablas fuente y final.

Lecciones clave

  • ClickHouse garantiza ACID solo para un único bloque en una partición; todo lo demás depende de la configuración.
  • La desduplicación de bloques por block_id causa pérdidas en INSERT interrumpidos dentro de pipelines de MV.
  • Desactivar insert_deduplicate resuelve el problema para MergeTree replicado.
  • Establecer deduplicate_blocks_in_dependent_materialized_views=1 previene pérdidas en las vistas.
  • Los duplicados tras desactivar la desduplicación se eliminan mediante fusiones estándar.

— Editorial Team

Advertisement 728x90

Leer después