INSERT ... SELECT. La configuración deduplicate_insert controla las inserciones síncronas y asíncronas. INSERT ... SELECT requiere especial atención y tiene su propia configuración. Consulte Configuraciones que controlan la deduplicación de inserciones.
Limitaciones
Estado incierto de la inserción
Límite de la ventana de deduplicación
*_deduplication_window operaciones de inserción adicionales, es posible que la deduplicación no funcione correctamente. En ese caso, los mismos datos pueden insertarse varias veces.
Configuraciones que controlan la deduplicación de inserciones
- La tabla de destino conserva un registro de deduplicación. Esta es una configuración a nivel de tabla.
- La deduplicación está habilitada para la consulta. Esta es una configuración a nivel de consulta.
Ajustes a nivel de tabla
*MergeTree admiten la deduplicación durante la inserción.
Para los motores *ReplicatedMergeTree, el registro de deduplicación está habilitado de forma predeterminada y se controla mediante los ajustes replicated_deduplication_window y replicated_deduplication_window_seconds. Para los motores *MergeTree no replicados, el registro se controla mediante el ajuste non_replicated_deduplication_window, cuyo valor predeterminado es 0. Por lo tanto, una tabla MergeTree simple no deduplica nada hasta que configure esa ventana con un valor positivo.
Los ajustes anteriores determinan los parámetros del registro de deduplicación de una tabla. El registro de deduplicación almacena un número finito de block_id, que determinan cómo funciona la deduplicación (véase más abajo).
replicated_deduplication_window_for_async_inserts y replicated_deduplication_window_seconds_for_async_inserts son ajustes heredados. Las inserciones síncronas y asíncronas ahora comparten un único registro de deduplicación, por lo que replicated_deduplication_window controla ambas. Los ajustes heredados solo delimitaban el antiguo directorio de ClickHouse Keeper, lo cual es relevante durante una actualización progresiva.Configuraciones a nivel de consulta
deduplicate_insert acepta tres valores:
enable— la deduplicación está habilitada para la consultaINSERT.disable— la deduplicación está deshabilitada para la consultaINSERT.backward_compatible_choice— la decisión se delega en las configuraciones heredadasinsert_deduplicate(inserciones síncronas) yasync_insert_deduplicate(inserciones asíncronas).
deduplicate_insert = disable no escribe ningún block_id para sus bloques. Esos datos no se pueden deduplicar posteriormente, incluso si vuelve a intentar la inserción con deduplicate_insert = enable. Lo mismo ocurre si la tabla de destino no conserva ningún registro de deduplicación: no se registra nada, por lo que no se puede encontrar ninguna coincidencia al volver a intentarlo.
Precedencia
- Para una consulta
INSERT ... SELECT, prevalecededuplicate_insert_select. Consulte Deduplicación para INSERT … SELECT. - Para cualquier otro
INSERT, prevalecededuplicate_insert. insert_deduplicateyasync_insert_deduplicatesolo se leen cuandodeduplicate_inserttiene el valorbackward_compatible_choice.
Configuraciones heredadas y obsoletas
La versión 26.2 también cambió los valores predeterminados de
async_insert y deduplicate_blocks_in_dependent_materialized_views a habilitados. La configuración compatibility controla las tres. Si establece compatibility en una versión anterior a 26.2, estas configuraciones conservan sus valores predeterminados anteriores: deduplicate_insert pasa a ser backward_compatible_choice, que delega la decisión en insert_deduplicate y async_insert_deduplicate. Una configuración establecida explícitamente siempre se respeta y nunca se ve afectada por compatibility.
Cómo funciona la deduplicación de inserciones
*MergeTree, a cada bloque se le asigna un block_id único, que es un hash de los datos de ese bloque. Este block_id se utiliza como clave única para la operación de inserción. Si se encuentra el mismo block_id en el registro de deduplicación, el bloque se considera duplicado y no se inserta en la tabla.
Este enfoque funciona bien cuando las inserciones contienen datos distintos. Sin embargo, si los mismos datos se insertan varias veces de forma intencionada, debes usar la configuración insert_deduplication_token para controlar el proceso de deduplicación. Esta configuración te permite especificar un token único para cada inserción, que ClickHouse utiliza para determinar si los datos están duplicados. insert_deduplication_token tiene mayor prioridad: ClickHouse no utiliza la suma hash de los datos cuando se proporciona el token.
Para las consultas INSERT ... VALUES, la división de los datos insertados en bloques es determinista y viene determinada por la configuración. Por lo tanto, debes reintentar las inserciones con los mismos valores de configuración que en la operación inicial.
Deduplicación para INSERT ... SELECT
INSERT ... SELECT, la parte SELECT debe devolver los mismos datos en el mismo orden en cada intento. De lo contrario, los bloques serán distintos, los block_ids también y el reintento no se reconocerá como duplicado.
ClickHouse no puede verificar que los datos de origen no hayan cambiado, pero sí puede comprobar si la consulta produce un resultado reproducible. Un SELECT se considera estable cuando se cumplen las dos condiciones siguientes:
- La consulta incluye una cláusula
ORDER BY ALL. Solo se reconoce el literalORDER BY ALL. Un simpleORDER BY <expressions>no se reconoce, y unUNIONde dos o másSELECTs nunca es estable. - La canalización de lectura termina en un único flujo.
insert_deduplication_token no vacío es un sustituto equivalente de la estabilidad, ya que el token, y no los datos, identifica la inserción.
La configuración deduplicate_insert_select determina qué hacer:
enable_when_possible y enable_even_for_bad_queries también respetan deduplicate_insert: si es disable, la consulta no se deduplica. force_enable sobrescribe deduplicate_insert.
Tenga en cuenta que la tabla seleccionada puede actualizarse entre reintentos. En ese caso, las dos opciones se comportan de forma opuesta:
- Sin
insert_deduplication_token, losblock_ids se calculan a partir de los datos. El resultado modificado generablock_ids distintos, no se produce la deduplicación y el reintento inserta los nuevos datos además de los que ya hubiera escrito el primer intento. - Con
insert_deduplication_token, el token por sí solo identifica la inserción. El reintento se reconoce como duplicado y se descarta, aunque hubiera insertado datos diferentes.
Deduplicación de inserciones asíncronas
async_insert, habilitadas de forma predeterminada desde la versión 26.2) se deduplican en los reintentos del mismo modo que las inserciones síncronas. deduplicate_insert controla ambas, por lo que no se requiere una opción independiente.
Ambos tipos de inserción también comparten un registro de deduplicación y calculan los block_id del mismo modo. Por lo tanto, puede alternar un client entre inserciones síncronas y asíncronas sin afectar a la deduplicación, y un reintento enviado en un modo seguirá reconociéndose como duplicado de un intento enviado en el otro. Migrar una carga de trabajo de inserciones síncronas a asíncronas sigue siendo seguro en una tabla que depende de la deduplicación.
Antes de la versión 26.2, la deduplicación de inserciones asíncronas estaba deshabilitada de forma predeterminada y se controlaba mediante
async_insert_deduplicate. Esta configuración ahora solo se consulta cuando deduplicate_insert es backward_compatible_choice.Granularidad de la deduplicación
- Cada consulta en cola aporta un token de deduplicación al lote.
- Un token es el valor de
insert_deduplication_token, cuando la consulta proporciona uno, o un hash de las filas aportadas por esa consulta. - La agrupación en lotes no influye en los tokens, y
insert_deduplication_tokenno influye en cómo se agrupan las consultas en lotes.
- Cuando una consulta de un lote es un duplicado, ClickHouse elimina solo las filas de esa consulta. El resto del lote se inserta normalmente. Una parte se omite por completo únicamente cuando se eliminan todas sus filas.
- Cuando dos consultas del mismo lote tienen el mismo token, la segunda se descarta antes de escribir la parte. Esto se aplica por partición: si las dos consultas escriben filas en particiones diferentes, ambas se conservan.
DuplicatedAsyncInserts y SelfDuplicatedAsyncInserts de system.events contabilizan estos dos casos.
Inserciones asíncronas y vistas materializadas
NOT_IMPLEMENTED.
Una vista genera un segundo bloque cuando su salida ya no cabe en un único bloque. max_block_size determina cuántas filas caben. Las transformaciones de columnas, el filtrado y la agregación nunca añaden filas, por lo que siempre permanecen en un único bloque. Un JOIN puede añadir filas. Funciona mientras el resultado se mantenga por debajo de max_block_size, pero falla si lo supera.
Para insertar mediante una vista que genera más de un bloque, establezca deduplicate_blocks_in_dependent_materialized_views = 0 o use inserciones síncronas.
Deduplicación de inserciones con vistas materializadas
replicated_deduplication_windowreplicated_deduplication_window_secondsnon_replicated_deduplication_window
deduplicate_blocks_in_dependent_materialized_views, que está habilitado de forma predeterminada desde la versión 26.2. Ambos ajustes deben permitirla: deduplicate_insert deduplica los datos insertados en la tabla de origen y deduplicate_blocks_in_dependent_materialized_views además deduplica los datos en las tablas dependientes. Habilite ambos si desea una deduplicación completa.
Al insertar bloques en tablas asociadas a vistas materializadas, ClickHouse calcula el block_id aplicando un hash a una cadena que combina los block_id de la tabla de origen con identificadores adicionales. Esto garantiza una deduplicación precisa dentro de las vistas materializadas, lo que permite distinguir los datos según su inserción original, independientemente de cualquier transformación aplicada antes de llegar a la tabla de destino de la vista materializada.
Ejemplos
Bloques idénticos tras las transformaciones de una vista materializada
dst. 2 bloques del select — 2 partes al insertar. Las partes contienen datos diferentes.
mv_dst. Esas partes contienen los mismos datos; sin embargo, no se han deduplicado.
dst como mv_dst.
Bloques idénticos al insertar
dst. Sin embargo, vemos que solo se ha insertado un bloque en la tabla dst. Esto ocurrió porque el segundo bloque se ha deduplicado. Tiene los mismos datos y la clave de deduplicación block_id, que se calcula como un hash a partir de los datos insertados. Este comportamiento no era el esperado. Estos casos son poco frecuentes, pero teóricamente son posibles. Para manejar estos casos correctamente, el usuario tiene que proporcionar un insert_deduplication_token. Corrijámoslo con los siguientes ejemplos:
Bloques idénticos durante la inserción con insert_deduplication_token
insert_deduplication_token tiene prioridad: ClickHouse no usa la suma hash de los datos cuando se proporciona insert_deduplication_token.
Diferentes operaciones de inserción generan los mismos datos tras la transformación en la tabla subyacente de la vista materializada
mv_dst se insertan los mismos datos. Los datos no se deduplican porque los datos de entrada eran distintos.
Diferentes inserciones de vistas materializadas en una misma tabla subyacente con datos equivalentes
mv_dst (como se esperaba).
dst y mv_dst.