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.
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:
- 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:
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
Aún no hay comentarios.