Cas 1 : INSERT dans une partition d’une table de la famille MergeTree*
- Atomicité : un INSERT réussit ou est rejeté dans son ensemble : si une confirmation est envoyée au client, toutes les lignes ont été insérées ; si une erreur est envoyée au client, aucune ligne n’a été insérée.
- Cohérence : si aucune contrainte de table n’est violée, toutes les lignes d’un INSERT sont insérées et l’INSERT réussit ; si des contraintes sont violées, aucune ligne n’est insérée.
- Isolation : les clients concurrents observent un instantané cohérent de la table — soit l’état de la table tel qu’il était avant la tentative d’INSERT, soit l’état après la réussite de l’INSERT ; aucun état partiel n’est visible. Les clients à l’intérieur d’une autre transaction bénéficient de l’isolation par instantané, tandis que les clients en dehors d’une transaction ont un niveau d’isolation lecture non validée.
- Durabilité : un INSERT réussi est écrit dans le système de fichiers avant qu’une réponse ne soit renvoyée au client, sur une seule réplique ou sur plusieurs répliques (contrôlé par le paramètre
insert_quorum), et ClickHouse peut demander à l’OS de synchroniser les données du système de fichiers sur le support de stockage (contrôlé par le paramètrefsync_after_insert). - Un INSERT dans plusieurs tables avec une seule instruction est possible si des vues matérialisées sont impliquées (l’INSERT du client vise une table à laquelle des vues matérialisées sont associées).
Cas 2 : INSERT dans plusieurs partitions d’une table de la famille MergeTree*
- Si la table comporte de nombreuses partitions et que l’INSERT en couvre plusieurs, alors l’insertion dans chaque partition constitue à elle seule une transaction
Cas 3 : INSERT dans une table distribuée de la famille MergeTree*
- l’INSERT dans une table Distributed n’est pas transactionnel dans son ensemble, tandis que l’insertion dans chaque segment l’est
Cas 4 : Utiliser une table Buffer
- les insertions dans les tables Buffer ne sont ni atomiques, ni isolées, ni cohérentes, ni durables
Cas 5 : utilisation de async_insert
- l’atomicité est garantie même si
async_insertest activé et quewait_for_async_insertest défini sur 1 (par défaut), mais siwait_for_async_insertest défini sur 0, alors l’atomicité n’est pas garantie.
Remarques
- les lignes insérées depuis le client dans un certain format de données sont regroupées dans un seul bloc lorsque :
- le format d’insertion est basé sur les lignes (comme CSV, TSV, Values, JSONEachRow, etc.) et que les données contiennent moins de
max_insert_block_sizelignes (~1 000 000 par défaut) ou moins demin_chunk_bytes_for_parallel_parsingoctets (10 Mo par défaut) si le parsing parallèle est utilisé (activé par défaut) - le format d’insertion est basé sur les colonnes (comme Native, Parquet, ORC, etc.) et que les données ne contiennent qu’un seul bloc de données
- le format d’insertion est basé sur les lignes (comme CSV, TSV, Values, JSONEachRow, etc.) et que les données contiennent moins de
- la taille du bloc inséré peut généralement dépendre de nombreux paramètres (par exemple :
max_block_size,max_insert_block_size,min_insert_block_size_rows,min_insert_block_size_bytes,preferred_block_size_bytes, etc.) - si le client n’a pas reçu de réponse du serveur, il ne sait pas si la transaction a abouti et peut répéter la transaction en s’appuyant sur les garanties d’insertion exactly-once
- ClickHouse utilise en interne MVCC avec isolation par instantané pour les transactions concurrentes
- toutes les propriétés ACID restent valides même en cas d’arrêt forcé ou de crash du serveur
- il faut activer soit
insert_quorumsur différentes AZ, soitfsyncafin de garantir la durabilité des insertions dans une configuration typique - la « cohérence » au sens d’ACID ne couvre pas la sémantique des systèmes distribués, voir https://jepsen.io/consistency ; cet aspect est contrôlé par d’autres paramètres (
select_sequential_consistency) - cette explication ne couvre pas la nouvelle fonctionnalité de transactions, qui permet d’avoir des transactions complètes sur plusieurs tables, des vues matérialisées, pour plusieurs SELECT, etc. (voir la section suivante sur Transactions, Commit, and Rollback)
Transactions, commit et rollback
Prérequis
- Déployez ClickHouse Keeper ou ZooKeeper pour suivre les transactions
- DB atomic uniquement (par défaut)
- Uniquement le moteur de table MergeTree non répliqué
- Activez la prise en charge expérimentale des transactions en ajoutant ce paramètre dans
config.d/transactions.xml:
Remarques
- Il s’agit d’une fonctionnalité expérimentale et des modifications sont à prévoir.
- Si une exception se produit pendant une transaction, vous ne pouvez pas valider la transaction. Cela inclut toutes les exceptions, y compris les exceptions
UNKNOWN_FUNCTIONcausées par des fautes de frappe. - Les transactions imbriquées ne sont pas prises en charge ; terminez la transaction en cours et démarrez-en une nouvelle
Configuration
Activer la prise en charge expérimentale des transactions
/etc/clickhouse-server/config.d/transactions.xml
Configuration de base pour un seul nœud ClickHouse server avec ClickHouse Keeper activé
Consultez la documentation sur le déploiement pour plus de détails sur le déploiement de ClickHouse server et sur un quorum adéquat de nœuds ClickHouse Keeper. La configuration présentée ici est fournie à titre expérimental.
/etc/clickhouse-server/config.d/config.xml
Exemple
Vérifiez que les transactions expérimentales sont activées
BEGIN TRANSACTION ou un START TRANSACTION, puis un ROLLBACK, afin de vérifier que les transactions expérimentales sont activées et que ClickHouse Keeper l’est également, car il sert à suivre les transactions.
Créer une table de test
Démarrer une transaction et insérer une ligne
Vous pouvez interroger la table dans une transaction et constater que la ligne a été insérée même si elle n’a pas encore été validée.
Annulez la transaction, puis interrogez de nouveau la table
Finaliser une transaction et interroger à nouveau la table
Introspection des transactions
system.transactions, mais notez que vous ne pouvez pas interroger cette
table depuis une session déjà engagée dans une transaction. Ouvrez une deuxième session clickhouse client pour interroger cette table.