Comment suivre le blocage qui se produit en moins d'une seconde - SQL Server


14

J'essaie de résoudre un problème de blocage qui se produit pendant moins d'une seconde. L'application OLTP est très sensible et doit avoir un temps de réponse inférieur à 200 ms pour certaines transactions conformément au SLA convenu. Nous avons eu quelques problèmes d'escalade de verrous avec la nouvelle version du code que nous avons pu résoudre en réduisant la taille du lot dans les mises à jour. Même avec la petite taille du lot, nous pensons que le nouveau sp bloque les mêmes lignes que les transactions OLTP sont en train de mettre à jour.

J'ai besoin de trouver la session bloquée et la ressource en attente. Selon ma compréhension, le «seuil de processus bloqué» peut être défini pour un minimum de 1 seconde et donc cela ne capturera pas le blocage.

J'expérimente avec wait_info et wait_completed x événements.

Existe-t-il un autre moyen de suivre cela. Merci


même question donc par le même utilisateur: stackoverflow.com/questions/38407021/…
TheGameiswar

Réponses:


10

Comme vous êtes spécifiquement intéressé par le verrouillage plutôt que par l'attente générale, l' locks_lock_waitsévénement étendu semble plus approprié.

Avec un filtre sur increment >= 200

CREATE EVENT SESSION [locks_lock_waits] ON SERVER 
ADD EVENT sqlserver.locks_lock_waits(
        ACTION(sqlserver.sql_text)
            WHERE  ( [sqlserver].[is_system] = 0
                     AND [increment] >= 200
                     AND [counter] <= 1000 ) 
    )
ADD TARGET package0.ring_buffer;

GO

ALTER EVENT SESSION [locks_lock_waits]  
ON SERVER  STATE = start;  

Ce qui précède rassemble les instructions en attente sur les verrous pendant la durée seuil, mais ne donne pas la ressource de verrouillage spécifique.

Je n'ai jamais utilisé cet événement et je n'ai aucune idée de la surcharge que cette session entraînerait sur votre serveur de production.

J'ai trouvé cette vidéo sur le sujet. Cela recommande fortement le filtrage counterpour réduire le nombre d'événements collectés et je l'ai fait ci-dessus.

Il mentionne également une ancienne commande non documentée héritée

dbcc lock(StallReportThreshold, 200) -- 200 is threshold in ms

Lequel (si l'indicateur de trace 3605 est activé) vide les informations limitées telles que celles ci-dessous dans le journal des erreurs SQL Server.

Le processus 53 a attendu 6844 ms pour le verrouillage S sur RID: résultat 2: 1: 120: 2: OKWAIT

Je mentionne juste ceci en passant car des événements prolongés seraient de toute façon clairement préférables car ils sont documentés et beaucoup plus puissants.


J'ai testé locks_lock_waits, et comme vous l'avez dit, il n'a pas d'informations sur les ressources. Mais je ne savais pas que l'augmentation était le temps. Bonne info verrouillage dbcc, fière allure. Savez-vous combien de temps ces informations sont disponibles avant de pouvoir être sauvegardées dans le journal des erreurs.
jesijesi

Désolé, je n'ai pas été clair. Je demandais combien de temps il nous reste avant d'exécuter la commande dbcc lock. Par exemple, le verrouillage se produit et si j'exécute le verrouillage dbcc après une heure, obtenons-nous toujours les informations?
jesijesi

@jesijesi - Je n'en avais jamais entendu parler avant aujourd'hui. Je n'ai plus d'informations à ce sujet. Je ne connais même pas les paramètres à passer pour le désactiver. Mais vous exécutez en dbcc lock(StallReportThreshold, 200) premier et il génère les informations une fois le seuil dépassé tant que l'indicateur de trace 3605 est activé. SQL Server ne collecte pas ces informations au cas où vous pourriez les exécuter plus tard.
Martin Smith

2
Merci. il suffit d'ajouter un lien qui a une fonction utile pour convertir les valeurs resource_0,1,2 dans xevents. sqlnotes.info/2011/10/24/…
jesijesi

5

Si vous êtes intéressé par le verrouillage, plusieurs événements étendus sont disponibles:

lock_acquired
lock_released
lock_escalation

Les deux premiers événements ont une durationcolonne en (microsecondes) sur laquelle vous pouvez filtrer pour vos seuils. Ils ont également une resource_descriptionaction qui vous donnera quelques détails sur les ressources impliquées.

L' lock_escalationévénement a également une statementaction que vous pouvez ajouter pour collecter l'instruction T-SQL qui a déclenché l'escalade du verrouillage. Il l'a également fait escalation_cause. Voici un exemple de session:

CREATE EVENT SESSION [locking] ON SERVER 
ADD EVENT sqlserver.lock_acquired( SET collect_resource_description = (1) ),
ADD EVENT sqlserver.lock_escalation( SET collect_statement = (1) ),
ADD EVENT sqlserver.lock_released( SET collect_resource_description = (1) )
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO

Je soupçonne qu'il y a probablement une raison pour laquelle vous ne pouvez pas définir le seuil de rapport de processus bloqué à moins d'une seconde: le verrouillage est parfaitement normal dans un SGBDR - le moteur de base de données doit verrouiller les ressources afin de les protéger. Bien qu'il n'y ait pas de définition officielle quant au moment où le verrouillage devient bloquant, le verrouillage du ticking en moins d'une seconde me semble un peu normal.


1
le verrouillage devient bloquant dès qu'une autre personne se voit refuser l'accès à la ressource et doit attendre en raison du verrou.
Martin Smith

Merci, je prévois d'utiliser lock_acquired avec le champ de durée.
jesijesi

Bonne chance. Comme vous êtes sur SQL Server 2014, vous pouvez utiliser des tables OLTP en mémoire avec des procs stockés compilés en mode natif offrant une option sans verrou haute performance. Vous pouvez également consulter l'isolement de l'instantané.
wBob
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.