Aller au contenu principal

Simultanéité au niveau des lignes

La concurrence au niveau des lignes réduit les conflits entre les opérations d'écriture concurrentes en détectant les modifications au niveau des lignes et en résolvant automatiquement les conflits qui se produisent lorsque des écritures concurrentes mettent à jour ou suppriment différentes lignes dans le même fichier de données.

Exigences pour la simultanéité au niveau des lignes

La concurrence au niveau des lignes est automatiquement activée lorsque toutes les exigences suivantes sont remplies :

  • Utilisation de Databricks Runtime 14.3 LTS et versions ultérieures.
  • La table source n'utilise pas de partitions.
  • Les vecteurs de suppression sont activés sur la table source. Découvrir les vecteurs de suppression dans Databricks.

Les tables partitionnées ne permettent pas la concurrence au niveau des lignes. Cependant, lorsque les vecteurs de suppression sont activés, les tables partitionnées peuvent toujours éviter les conflits entre OPTIMIZE et les opérations d'écriture. Consultez Limitations pour la concurrence au niveau des lignes.

Pour les versions de Databricks Runtime antérieures à 14.3 LTS, consultez Comportement hérité de la concurrence au niveau des lignes.

Matrice de conflit avec concomitance au niveau des lignes

Pour les tables source avec concurrence au niveau des lignes, le tableau suivant indique quelles paires d'opérations d'écriture peuvent entrer en conflit dans chaque niveau d'isolation :

Opérations

INSERT (1)

UPDATE, DELETE, MERGE INTO

OPTIMIZE

INSÉRER

Impossible d'entrer en conflit

UPDATE, DELETE, MERGE INTO

Impossible de générer un conflit dans WriteSerializable. Un conflit peut survenir en sérialisable lors de la modification de la même ligne.

Peut y avoir un conflit lors de la modification de la même ligne.

OPTIMIZE

Impossible d'entrer en conflit

Peut entrer en conflit lorsque ZORDER BY est utilisé. Ne peut pas être en conflit autrement.

Peut entrer en conflit lorsque ZORDER BY est utilisé. Ne peut pas être en conflit autrement.

Opérations

INSERT (1)

UPDATE, DELETE, MERGE INTO

OPTIMIZE

INSÉRER

Impossible d'entrer en conflit

UPDATE, DELETE, MERGE INTO

Impossible de générer un conflit dans WriteSerializable. Un conflit peut survenir en sérialisable lors de la modification de la même ligne.

Peut y avoir un conflit lors de la modification de la même ligne.

OPTIMIZE

Impossible d'entrer en conflit

Peut entrer en conflit lorsque ZORDER BY est utilisé. Ne peut pas être en conflit autrement.

Peut entrer en conflit lorsque ZORDER BY est utilisé. Ne peut pas être en conflit autrement.

(1) Toutes les INSERT opérations de cette table décrivent des opérations d'ajout qui ne contiennent pas de sous-requêtes lisant les données de la même table. Les INSERT Opérations contenant des sous-requêtes qui lisent la même table prennent en charge la même concurrence que les MERGE.

remarque
  • Les tables avec colonnes d’identité ne prennent pas en charge les transactions simultanées. Voir les colonnes d'identité.
  • REORG les opérations ont une sémantique d’isolation identique à OPTIMIZE lors de la réécriture des fichiers de données. Lorsque vous utilisez REORG pour appliquer une mise à niveau, les protocoles de table changent, ce qui entre en conflit avec toutes les opérations en cours.

Conflits d'écriture sans concurrence au niveau des lignes

Pour les tables sources sans concurrence au niveau des lignes, le tableau suivant indique quelles paires d'opérations d'écriture peuvent entrer en conflit à chaque niveau d'isolement :

Opérations

INSERT (1)

UPDATE, DELETE, MERGE INTO

OPTIMIZE

INSÉRER

Impossible d'entrer en conflit

UPDATE, DELETE, MERGE INTO

Impossible de générer un conflit dans WriteSerializable. Peut entrer en conflit en mode Serializable. Voir Éviter les conflits à l’aide du partitionnement.

Peut y avoir conflit dans les modes sérialisable et sérialisable en écriture. Voir Éviter les conflits à l'aide du partitionnement.

OPTIMIZE

Impossible d'entrer en conflit

Ne peut pas entrer en conflit dans les tables avec les vecteurs de suppression activés, sauf si ZORDER BY est utilisé. Peut entrer en conflit sinon.

Ne peut pas entrer en conflit dans les tables avec les vecteurs de suppression activés, sauf si ZORDER BY est utilisé. Peut entrer en conflit sinon.

Opérations

INSERT (1)

UPDATE, DELETE, MERGE INTO

OPTIMIZE

INSÉRER

Impossible d'entrer en conflit

UPDATE, DELETE, MERGE INTO

Impossible de générer un conflit dans WriteSerializable. Peut entrer en conflit en mode Serializable. Voir Éviter les conflits à l’aide du partitionnement.

Peut y avoir conflit dans les modes sérialisable et sérialisable en écriture. Voir Éviter les conflits à l'aide du partitionnement.

OPTIMIZE

Impossible d'entrer en conflit

Ne peut pas entrer en conflit dans les tables avec les vecteurs de suppression activés, sauf si ZORDER BY est utilisé. Peut entrer en conflit sinon.

Ne peut pas entrer en conflit dans les tables avec les vecteurs de suppression activés, sauf si ZORDER BY est utilisé. Peut entrer en conflit sinon.

(1) Toutes les INSERT opérations de cette table décrivent des opérations d'ajout qui ne contiennent pas de sous-requêtes lisant les données de la même table. Les INSERT Opérations contenant des sous-requêtes qui lisent la même table prennent en charge la même concurrence que les MERGE.

remarque
  • Les tables avec colonnes d’identité ne prennent pas en charge les transactions simultanées. Voir les colonnes d'identité.
  • REORG les opérations ont une sémantique d’isolation identique à OPTIMIZE lors de la réécriture des fichiers de données. Lorsque vous utilisez REORG pour appliquer une mise à niveau, les protocoles de table changent et entrent en conflit avec toutes les opérations en cours.

Limitations pour la concurrence au niveau des lignes

Des limitations s'appliquent à la concurrence au niveau des lignes. Pour les opérations suivantes, la résolution des conflits suit la concurrence normale pour les conflits d'écriture. Voir Conflits d'écriture sans concurrence au niveau des lignes.

Limitation

Description

Clauses conditionnelles complexes.

Conditions sur les types de données complexes (structures, tableaux, maps), expressions non déterministes, sous-requêtes et sous-requêtes corrélées

MERGE exigence de prédicat

Dans Databricks Runtime 14.2, les commandes MERGE doivent utiliser un prédicat explicite sur la table cible pour filtrer les lignes correspondant à la table source

Compromis de performance

La détection des conflits au niveau des lignes peut augmenter le temps d'exécution total. Avec de nombreuses transactions concurrentes, le processus d'écriture privilégie la latence à la résolution des conflits.

Limitation

Description

Clauses conditionnelles complexes.

Conditions sur les types de données complexes (structures, tableaux, maps), expressions non déterministes, sous-requêtes et sous-requêtes corrélées

MERGE exigence de prédicat

Dans Databricks Runtime 14.2, les commandes MERGE doivent utiliser un prédicat explicite sur la table cible pour filtrer les lignes correspondant à la table source

Compromis de performance

La détection des conflits au niveau des lignes peut augmenter le temps d'exécution total. Avec de nombreuses transactions concurrentes, le processus d'écriture privilégie la latence à la résolution des conflits.

Toutes les limitations pour les vecteurs de suppression s'appliquent également. Consulter Limitations.

Évitez les conflits à l'aide du partitionnement

Dans tous les cas marqués "peut entrer en conflit" dans les matrices de conflits, un conflit ne se produit que si les deux opérations affectent le même ensemble de fichiers. Pour rendre deux ensembles de fichiers disjoints, partitionnez la table par les mêmes colonnes utilisées dans les conditions d'opération.

Exemple :

Les commandes UPDATE table WHERE date > '2010-01-01' ... et DELETE table WHERE date < '2010-01-01' sont en conflit si la table n'est pas partitionnée par date, car les deux peuvent tenter de modifier les mêmes fichiers. Le partitionnement de la table par date évite le conflit.

remarque

Le partitionnement d'une table par une colonne à cardinalité élevée peut entraîner des problèmes de performance en raison du grand nombre de sous-répertoires.

Évitez les conflits avec les filtres de partition explicites

Cette exception est souvent levée lors d’opérations DELETE, UPDATE ou MERGE concurrentes qui pourraient lire la même partition même lors de la mise à jour de partitions différentes. Rendre la séparation explicite dans la condition d’opération :

Scala
// Problem: Condition can scan the entire table
deltaTable.as("t").merge(
source.as("s"),
"s.user_id = t.user_id AND s.date = t.date AND s.country = t.country")
.whenMatched().updateAll()
.whenNotMatched().insertAll()
.execute()

// Solution: Add explicit partition filters
deltaTable.as("t").merge(
source.as("s"),
"s.user_id = t.user_id AND s.date = t.date AND s.country = t.country AND t.date = '" + date + "' AND t.country = '" + country + "'")
.whenMatched().updateAll()
.whenNotMatched().insertAll()
.execute()

Exceptions de conflit

Lorsqu'un conflit de transaction se produit, vous observez l'une des exceptions suivantes :

ConcurrentAppendException

Cette exception se produit lorsqu'une opération concurrente ajoute des fichiers dans la même partition (ou n’importe où dans une table non partitionnée) que celle que votre opération lit. Les ajouts de fichiers peuvent être causés par les opérations INSERT, DELETE, UPDATE ou MERGE.

Avec le niveau d’isolation WriteSerializable par default, les fichiers ajoutés par les Opérations INSERT qui ajoutent des données sans en lire n’entrent pas en conflit avec aucune Opération. Si le niveau d'isolation est sérialisable, toutes les opérations d'ajout peuvent entrer en conflit.

important

INSERT Les opérations peuvent entrer en conflit en mode WriteSerializable si plusieurs opérations DELETE, UPDATE ou MERGE simultanées peuvent référencer des valeurs ajoutées par l'opération INSERT. Pour éviter cela :

  • Assurez-vous que les opérations DELETE, UPDATE ou MERGE concurrentes ne lisent pas les données ajoutées.
  • Avoir au maximum une opération DELETE, UPDATE ou MERGE qui peut lire les données ajoutées

ConcurrentDeleteReadException

Cette exception se produit lorsqu’une opération concurrente supprime un fichier que votre opération a lu. Les causes courantes sont les opérations DELETE, UPDATE ou MERGE qui réécrivent les fichiers.

ConcurrentDeleteDeleteException

Cette exception se produit lorsqu'une Opération concurrente supprime un fichier que votre Opération supprime également. Cela pourrait être causé par deux Opérations de compaction concurrentes réécrivant les mêmes fichiers.

MetadataChangedException

Cette exception se produit lorsqu'une transaction concurrente met à jour les métadonnées d'une table Delta. Les causes courantes sont des ALTER TABLE opérations ou des écritures qui mettent à jour le schéma de la table.

ConcurrentTransactionException

Cette exception se produit si une query de streaming utilisant le même emplacement de point de contrôle est start plusieurs fois simultanément et tente d'écrire dans la table Delta en même temps. Ne lancez jamais deux queries de streaming avec le même emplacement de point de contrôle simultanément.

ProtocolChangedException

Cette exception peut se produire lorsque :

  • Votre table Delta Lake est mise à niveau vers une nouvelle version de protocole (vous devrez peut-être mettre à niveau votre Databricks Runtime)
  • Plusieurs rédacteurs créent ou remplacent une table en même temps
  • Plusieurs rédacteurs écrivent vers un chemin vide en même temps

Consultez la compatibilité des fonctionnalités et les protocoles de Delta Lake.

Comportement hérité de la concurrence au niveau des lignes

Dans Databricks Runtime 13.3 LTS, la concurrence au niveau des lignes utilise le comportement hérité :

  • Requiert des vecteurs de suppression. Découvrir les vecteurs de suppression dans Databricks.
  • Les tables avec clustering liquide activent automatiquement la simultanéité au niveau des lignes.

Ressources supplémentaires