Je reçois un blocage lors de l'exécution d'un travail SQL Server. Le blocage se produit sur une simple instruction DELETE. J'aurais pensé qu'il devrait y avoir une requête SELECT / UPDATE en cours d'exécution pour provoquer le blocage? Mais il semble que ce soit DELETE / DELETE deadlock ...
Ce que je recherche, c'est pourquoi j'obtiens un blocage DELETE / DELETE. Il s'agit (à ma connaissance) de différents paramètres.
Des idées? Merci.
deadlock-list
2014-05-20 07:30:09.66 spid25s deadlock victim=process409048
2014-05-20 07:30:09.66 spid25s process-list
2014-05-20 07:30:09.66 spid25s process id=process409048 taskpriority=0 logused=0 waitresource=PAGE: 12:1:7127294 waittime=4352 ownerId=629860973 transactionname=DELETE lasttranstarted=2014-05-20T07:30:05.307 XDES=0x397219620 lockMode=U schedulerid=5 kpid=3792 status=suspended spid=150 sbid=0 ecid=3 priority=0 trancount=0 lastbatchstarted=2014-05-20T07:30:05.307 lastbatchcompleted=2014-05-20T07:30:05.307 clientapp=QSQL25 hostname=MORRIS hostpid=1528 isolationlevel=read committed (2) xactid=629860973 currentdb=12 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
2014-05-20 07:30:09.66 spid25s executionStack
2014-05-20 07:30:09.66 spid25s frame procname=adhoc line=1 stmtstart=68 sqlhandle=0x020000000b887a18f75d0aa07c25a9b8630fca696aa0e5d2
2014-05-20 07:30:09.66 spid25s DELETE FROM dbo.UserDetailsData WHERE (Username = @P1) AND (UserDate = @P2)
2014-05-20 07:30:09.66 spid25s frame procname=unknown line=1 sqlhandle=0x000000000000000000000000000000000000000000000000
2014-05-20 07:30:09.66 spid25s unknown
2014-05-20 07:30:09.66 spid25s inputbuf
2014-05-20 07:30:09.66 spid25s process id=process432e08 taskpriority=0 logused=0 waitresource=PAGE: 12:1:7127916 waittime=2648 ownerId=629859744 transactionname=DELETE lasttranstarted=2014-05-20T07:30:04.833 XDES=0x4c3426b50 lockMode=U schedulerid=6 kpid=5988 status=suspended spid=146 sbid=0 ecid=3 priority=0 trancount=0 lastbatchstarted=2014-05-20T07:30:04.833 lastbatchcompleted=2014-05-20T07:30:04.820 clientapp=QSQL25 hostname=MORRIS hostpid=1528 isolationlevel=read committed (2) xactid=629859744 currentdb=12 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
2014-05-20 07:30:09.66 spid25s executionStack
2014-05-20 07:30:09.66 spid25s frame procname=adhoc line=1 stmtstart=68 sqlhandle=0x020000000b887a18f75d0aa07c25a9b8630fca696aa0e5d2
2014-05-20 07:30:09.66 spid25s DELETE FROM dbo.UserDetailsData WHERE (Username = @P1) AND (UserDate = @P2)
2014-05-20 07:30:09.66 spid25s frame procname=unknown line=1 sqlhandle=0x000000000000000000000000000000000000000000000000
2014-05-20 07:30:09.66 spid25s unknown
2014-05-20 07:30:09.66 spid25s inputbuf
2014-05-20 07:30:09.66 spid25s process id=process39ea562c8 taskpriority=0 logused=0 waitresource=PAGE: 12:1:7127916 waittime=4352 ownerId=629860973 transactionname=DELETE lasttranstarted=2014-05-20T07:30:05.307 XDES=0x13e0e4b50 lockMode=U schedulerid=2 kpid=7124 status=suspended spid=150 sbid=0 ecid=1 priority=0 trancount=0 lastbatchstarted=2014-05-20T07:30:05.307 lastbatchcompleted=2014-05-20T07:30:05.307 clientapp=QSQL25 hostname=MORRIS hostpid=1528 isolationlevel=read committed (2) xactid=629860973 currentdb=12 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
2014-05-20 07:30:09.66 spid25s executionStack
2014-05-20 07:30:09.66 spid25s frame procname=adhoc line=1 stmtstart=68 sqlhandle=0x020000000b887a18f75d0aa07c25a9b8630fca696aa0e5d2
dbo.UserDetailsData
inclure tous les index? De plus, savez-vous si ces instructions sont appelées avec les mêmes paramètres? Étant donné que les deux n'ont aucun journal utilisé, je me demande si tout ce que vous avez à faire est de sérialiser les appels, car ils se marchent les uns sur les autres.Réponses:
Il semble que l'impasse se produise parce que:
spid 54 ecid 0
acquiert unU
verrou de page update ( ) surPAGE: 12:1:5147422
spid 166 ecid 3
demande unU
verrouillage de page update ( ) sur la même page et est bloquéspid 54 ecid 2
demande unU
verrouillage de page update ( ) sur la même page ...Les pages sont en cours de prélecture pour la requête, avec des verrous de mise à jour acquis par
ecid 0
. C'est l'étape 1 ci-dessus. À l'étape 3, un thread enfant de la même requête parallèle (ecid 2
) demande le même verrou. Normalement, ce ne serait pas un problème. SQL Server connaîtecid 0
etecid 2
sont des threads du même processus parent. Malheureusement, l'étape 2 se met en travers de cela et une impasse se produit.Cela dit, vous ne devriez pas vraiment vous soucier de la raison pour laquelle l'impasse se produit, la question importante est de savoir comment l'éviter. La réponse est de fournir un chemin d'accès efficace pour le
DELETE
. L'instruction doit trouver des lignesWHERE Username = @P1 AND UserDate = @P2
, vous devez donc avoir un index sur ces colonnes.Et bien sûr, vous avez un tel indice. La vraie question est de savoir pourquoi vos problèmes ont commencé à se produire après avoir ajouté des index filtrés.
La réponse à cette question est que des informations supplémentaires sur les colonnes sont nécessaires pour localiser les lignes d'index filtrées à supprimer (et pour vérifier leurs prédicats). Si la requête utilise un plan d'exécution étroit / par ligne , le moteur d'exécution ne peut pas récupérer les colonnes supplémentaires dans l'opérateur de suppression d'index en cluster, comme il le ferait dans un plan large / par index.
Vous pouvez trouver plus de détails à ce sujet et un exemple concret dans cet article de blog .
Dans ce cas, les informations de colonne doivent provenir de la partie du plan à droite de la suppression d'index en cluster, et donc une analyse d'index en cluster parallèle est utilisée, et vous obtenez une requête lente avec un potentiel de blocage élevé.
La réponse consiste à effectuer l'une des opérations suivantes:
L'option 2 serait ma préférence.
L'option 4 (merci Jack Douglas) a l'avantage de supprimer les blocages et ne devrait pas provoquer de "conflits de mise à jour", étant donné la nature disjointe des changements, mais elle nécessite l'activation de l'isolement de l'instantané au niveau de la base de données, modifiant explicitement le niveau d'isolement, et ne résoudra pas le problème sous-jacent : vous vous retrouverez toujours avec une analyse de table parallèle inutile, où une belle recherche d'index est ce que vous voulez vraiment.
la source