Skip to main content
La plupart des requêtes ALTER TABLE modifient les paramètres ou les données d’une table :
La plupart des requêtes ALTER TABLE ne sont prises en charge que pour les tables *MergeTree, Merge et Distributed.
Ces instructions ALTER s’appliquent aux vues : Ces instructions ALTER modifient les entités liées au contrôle d’accès basé sur les rôles :

Mutations

Les requêtes ALTER destinées à modifier les données des tables sont mises en œuvre au moyen d’un mécanisme appelé « mutations », notamment ALTER TABLE … DELETE et ALTER TABLE … UPDATE. Il s’agit de processus asynchrones en arrière-plan, similaires aux fusions dans les tables MergeTree, qui produisent de nouvelles versions « mutées » des parts. Pour les tables *MergeTree, les mutations s’exécutent en réécrivant des data parts entières. Il n’y a pas d’atomicité — les parts sont remplacées par leurs versions mutées dès qu’elles sont prêtes, et une requête SELECT dont l’exécution a commencé pendant une mutation verra à la fois des données provenant de parts déjà mutées et de parts qui ne l’ont pas encore été. Les mutations sont totalement ordonnées selon leur ordre de création et sont appliquées à chaque part dans cet ordre. Les mutations sont également partiellement ordonnées par rapport aux requêtes INSERT INTO : les données insérées dans la table avant la soumission de la mutation seront mutées, et celles insérées après ne le seront pas. Notez que les mutations ne bloquent en aucune façon les insertions. Une requête de mutation renvoie immédiatement après l’ajout de l’entrée de mutation (dans le cas des tables répliquées, dans ZooKeeper ; pour les tables non répliquées, dans le système de fichiers). La mutation elle-même s’exécute de manière asynchrone en utilisant les paramètres du profil système. Pour suivre la progression des mutations, vous pouvez utiliser la table system.mutations. Une mutation soumise avec succès continuera à s’exécuter même si les serveurs ClickHouse sont redémarrés. Il n’existe aucun moyen de revenir sur une mutation une fois qu’elle a été soumise, mais si elle est bloquée pour une raison quelconque, elle peut être annulée avec la requête KILL MUTATION. Les entrées des mutations terminées ne sont pas supprimées immédiatement (le nombre d’entrées conservées est déterminé par le paramètre du moteur de stockage finished_mutations_to_keep). Les entrées de mutation plus anciennes sont supprimées.

Exécution synchrone des requêtes ALTER

Pour les tables non répliquées, toutes les requêtes ALTER sont exécutées de manière synchrone. Pour les tables répliquées, la requête se contente d’ajouter dans ZooKeeper les instructions correspondant aux actions appropriées, et ces actions sont ensuite exécutées dès que possible. Toutefois, la requête peut attendre que ces actions soient terminées sur toutes les répliques. Pour les requêtes ALTER qui créent des mutations (par ex. : UPDATE, DELETE, MATERIALIZE INDEX, MATERIALIZE PROJECTION, MATERIALIZE COLUMN, APPLY DELETED MASK, APPLY PATCHES, CLEAR STATISTIC, MATERIALIZE STATISTIC, entre autres), le caractère synchrone est défini par le paramètre mutations_sync. Pour les autres requêtes ALTER qui modifient uniquement les métadonnées, vous pouvez utiliser le paramètre alter_sync pour définir l’attente. Vous pouvez spécifier, avec le paramètre replication_wait_for_inactive_replica_timeout, combien de temps (en secondes) attendre que les répliques inactives exécutent toutes les requêtes ALTER.
Pour toutes les requêtes ALTER, si alter_sync = 2 et que certaines répliques restent inactives au-delà de la durée spécifiée par le paramètre replication_wait_for_inactive_replica_timeout, une exception UNFINISHED est levée.

Attribution concurrente d’ALTER sur une même table

Sur les tables répliquées, l’envoi rapide de plusieurs instructions ALTER distinctes sur une même table peut échouer avec CANNOT_ASSIGN_ALTER (code 517). Le chemin de réplication déclenche cette erreur lorsque la réplique n’a pas encore appliqué certains ALTER précédents (la version des métadonnées est toujours en retard par rapport aux métadonnées communes — le serveur peut indiquer que la réplique « still not applied some of previous alters » ou « Probably too many alters executing concurrently »). Cette condition peut persister même lorsqu’un ALTER précédent a déjà été attribué. Il s’agit d’une condition générale de concurrence entre ALTER de métadonnées et mutations — elle ne se limite pas aux instructions produisant uniquement des mutations. Des modifications concurrentes ordinaires des métadonnées (ADD / DROP / MODIFY et similaires) peuvent déclencher le même code pouvant donner lieu à un réessai (voir, par exemple, le chemin de réessai couvert par tests/queries/0_stateless/03518_alter_logical_race.sh). Approches permettant d’éviter la condition de concurrence :
  • Regroupez les opérations de métadonnées indépendantes dans un unique ALTER comportant plusieurs clauses lorsque la grammaire le permet (par exemple, plusieurs clauses ADD INDEX).
  • Sérialisez les instructions ALTER et réessayez en cas de code 517 jusqu’à ce que les ALTER précédents aient été appliqués sur la réplique.
  • Pour les ALTER produisant des mutations, attendez la fin de la mutation précédente à l’aide d’un indicateur observable documenté, tel que mutations_sync ou is_done dans system.mutations, avant d’envoyer la suivante.

Combinaison de clauses MATERIALIZE INDEX

Plusieurs clauses MATERIALIZE INDEX peuvent figurer dans une même instruction ALTER. Le cas couvert dans le code source consiste à regrouper plusieurs clauses ADD INDEX et les clauses MATERIALIZE INDEX correspondantes pour ces nouveaux index dans une seule instruction (voir tests/queries/0_stateless/02911_add_index_and_materialize_index.sql). Cette forme combinant ADD INDEX et MATERIALIZE INDEX mêle un segment AlterCommand à un segment MutationCommand ; DatabaseReplicated la rejette donc avec QUERY_IS_PROHIBITED (InterpreterAlterQuery::validateReplicatedDatabaseSegments). Considérez l’exemple 02911 comme valide pour les bases de données ordinaires (non-DatabaseReplicated) ; avec DatabaseReplicated, conservez les modifications de métadonnées et les mutations de matérialisation dans des instructions distinctes. Dans l’implémentation actuelle, chaque clause MATERIALIZE INDEX est résolue par rapport à l’instantané des métadonnées de la table lors de la préparation de la mutation. Les formes à plusieurs clauses qui ne font que matérialiser des index déjà existants suivent donc le même chemin de préparation (mutation uniquement, elles restent donc dans un seul segment). Cette forme précise n’est pas encore couverte par un test stateless ciblé ; considérez-la comme un comportement de l’implémentation actuelle plutôt que comme une garantie distincte tant qu’une telle couverture n’existe pas. Si vous avez besoin d’appliquer les mutations dans un ordre précis, vous pouvez toujours émettre une instruction MATERIALIZE INDEX par instruction et attendre avec mutations_sync.
Dernière modification le 14 août 2026