Résoudre les problèmes de blocage des requêtes dans Fabric Data Warehouse

S’applique à :✅Entrepôt dans Microsoft Fabric

Si vos requêtes dans l’entrepôt prennent un certain temps pour s’exécuter ou semblent bloquées, une cause possible est le verrouillage. Le verrouillage se produit lorsqu’une session contient un verrou qui empêche d’autres requêtes de continuer.

Cet article vous montre comment déterminer si le verrouillage affecte votre charge de travail et quelles actions vous pouvez effectuer.

Tip

L’entrepôt utilise le verrouillage au niveau de la table. Toute opération DML acquiert un verrou sur la table entière, quel que soit le nombre de lignes affectées. Ce comportement est différent de SQL Server, qui prend en charge les verrous au niveau des lignes et des pages.

Prerequisites

  • Entrepôt avec charges de travail actives.
  • L’appartenance au rôle Lecteur de l’espace de travail est l’autorisation minimale requise pour interroger les vues de gestion dynamique (DMV) mentionnées dans cet article.

Étape 1 : Vérifier si les requêtes attendent des verrous

Commencez par vérifier si des requêtes attendent actuellement des verrous.

Exécutez la requête suivante :

SELECT
    request_session_id,
    resource_type,
    resource_description,
    request_mode,
    request_status
FROM sys.dm_tran_locks
WHERE request_status = 'WAIT';

Si la requête retourne des lignes, certaines sessions attendent des ressources détenues par d’autres sessions. Chaque ligne indique une demande de verrouillage qui ne peut pas être accordée actuellement.

Tip

La vue sys.dm_tran_locks peut renvoyer un grand nombre de lignes pour les verrous accordés. Le filtrage par request_status = 'WAIT' se concentre sur les sessions bloquées.

Étape 2 : Identifier les requêtes bloquées

Ensuite, vérifiez quelles requêtes sont bloquées et quelle session les bloque.

SELECT
    session_id,
    status,
    blocking_session_id,
    wait_type,
    total_elapsed_time,
    open_transaction_count
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;

Cette requête renvoie :

  • Session exécutant la requête bloquée (session_id)
  • La session le bloque actuellement (blocking_session_id)
  • Durée d’attente (total_elapsed_timeen millisecondes)
  • Indique si la session bloquante a une transaction ouverte (open_transaction_count)

Si une requête indique que blocking_session_id est non nul et open_transaction_count > 0, elle attend une autre session qui détient un verrou.

Étape 3 : Rechercher la session bloquante

Pour comprendre quelle ressource est verrouillée, inspectez les verrous actuellement conservés par la session bloquante. Remplacez un session_id élément que vous avez identifié précédemment pour l’exemple <blocking_session_id> de requête suivant :

SELECT
    request_session_id,
    resource_type,
    resource_associated_entity_id,
    request_mode,
    request_status
FROM sys.dm_tran_locks
WHERE
    request_status = 'GRANT'
    AND request_session_id = <blocking_session_id>;

Utilisez cette requête pour déterminer :

  • Les ressources sur lesquelles la session bloquante détient actuellement des verrous. Par exemple, vous pouvez utiliser sys.objects pour identifier le resource_associated_entity_id où le resource_type = OBJECT.
  • Mode de verrouillage (par exemple, Exclusif (X), Schema-Modification (Sch-M))
  • Indique si le verrou est lié à une opération DDL ou à une mise à jour des statistiques (UPDSTATS)

Note

Les verrous liés aux statistiques (tels que ceux de UPDSTATS) apparaissent également dans sys.dm_tran_locks. Les verrous Schema-Modification (Sch-M) et Exclusive (X) sont les sources de blocage les plus courantes, mais tout type de verrou peut bloquer une requête incompatible (par exemple, un verrou Sch-S bloque Sch-M).

Étape 4 : Rechercher le propriétaire de la transaction bloquante

Dans de nombreux cas, vous préférerez peut-être demander au propriétaire de la transaction bloquante de COMMIT ou ROLLBACK son travail au lieu de terminer la session. Envisagez d’utiliser des TRYCATCH structures pour la gestion des erreurs avec COMMIT ou ROLLBACK. Pour plus d’informations, consultez TRY... CATCH.

Vous pouvez identifier le propriétaire et la requête associées à la session de blocage. Remplacez un session_id élément que vous avez identifié précédemment pour l’exemple <blocking_session_id> de requête suivant :

SELECT
    r.session_id,
    s.login_name,
    s.program_name,
    r.status,
    r.blocking_session_id,
    r.command,
    r.total_elapsed_time,
    s.last_request_start_time,
    s.last_request_end_time
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s
    ON r.session_id = s.session_id
WHERE r.session_id = <blocking_session_id>;
  • login_name est le propriétaire de la session bloquante.
  • program_name est l’application qui a lancé la session. La DMS_user valeur indique l’éditeur de requête du portail Fabric.
  • command est la commande en cours d’exécution.

Vous pouvez ensuite contacter le propriétaire de la transaction pour la valider ou l’annuler, si nécessaire.

Étape 5 : Vérifier si la session bloquante est inactive ou ne progresse pas

Une session bloquante peut apparaître active, mais n’effectue pas réellement de progression.

Les indicateurs d’une session inactive ou bloquée sont les suivants :

  • status = 'sleeping' indique qu’aucune requête active n’est en cours d’exécution.
  • Recherchez un last_request_start_time nettement antérieur à l’heure actuelle, indiquant une requête ouverte depuis longtemps.
  • Recherchez un total_elapsed_time qui n’augmente pas d’une vérification à l’autre, ce qui indique une session bloquée.
SELECT
    session_id,
    status,
    last_request_start_time,
    last_request_end_time,
    open_transaction_count
FROM sys.dm_exec_sessions
WHERE session_id = <blocking_session_id>;
  • Si l’état de la session est sleeping et open_transaction_count > 0, cela signifie que la session a une transaction ouverte sans requête active : elle détient un verrou sans exécuter de travail.
  • Si la session apparaît dans sys.dm_exec_requests et que total_elapsed_time continue d’augmenter entre les vérifications, la session est en cours de progression. Il peut être préférable d’attendre que la transaction s’achève plutôt que de l’interrompre et d’en forcer l’annulation.

Étape 6 : Prendre des mesures pour résoudre le blocage

Note

Les situations de blocage se résolvent souvent par eux-mêmes une fois la session bloquante terminée sa transaction. Si votre charge de travail peut tolérer le délai, l’attente est l’option la plus sûre.

Si vous devez débloquer des requêtes en aval, envisagez si une session bloquante présente les caractéristiques suivantes :

  • A une transaction ouverte
  • S’affiche inactif ou ne progresse pas
  • Détient un verrou bloquant (par exemple, verrou exclusif (X) ou Sch-M)

Si c’est le cas, un membre du rôle d’espace de travail Administrateur peut terminer une session à l’aide de :

KILL <session_id>;

La commande KILL va :

  • Terminer la session
  • Annuler toutes les opérations effectuées dans la transaction active de cette session
  • Libérer le verrou
  • Autoriser les requêtes en aval à se poursuivre

Caution

Tuer une session annule tout travail non validé effectué par cette session. Cette action peut annuler les modifications apportées aux données apportées par l’utilisateur ou l’application. Utilisez cette option uniquement lorsque vous êtes certain que la fin de la transaction n’affecte pas négativement votre charge de travail.

Étape 7 : Empêcher les futurs problèmes de verrouillage

Pour éviter des problèmes similaires :

  • Évitez de laisser les transactions explicites ouvertes (BEGIN TRANSACTION sans correspondance COMMIT ou ROLLBACK).
  • Conservez les transactions de courte durée. Effectuez uniquement les opérations nécessaires dans la transaction.
  • Toujours COMMIT ou ROLLBACK les transactions une fois terminées.
  • Planifiez des opérations DDL (par exemple ALTER TABLE) pendant les fenêtres à faible trafic.

Surveillez de manière proactive les transactions ouvertes à l’aide de :

SELECT
    session_id,
    login_name,
    open_transaction_count,
    program_name,
    status,
    blocking_session_id,
    last_request_start_time
FROM sys.dm_exec_sessions
WHERE open_transaction_count > 0;

La surveillance régulière des transactions ouvertes et l’intervention en cas de besoin permet de réduire la probabilité de former des chaînes bloquantes.