web-dev-qa-db-fra.com

Puis-je résoudre une impasse avec l'indice Rowlock?

J'ai un grand nombre de procès stocké et j'ai reproduit une impasse dans une situation où les suppressions n'auraient rien supprimé.

Cela ressemble à la partie du procédé stocké qui a frappé une impasse était comme ceci (noms de table modifiés):

DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId

Il me semble que deux suppressions fonctionnaient simultanément en même temps et une impasse pour tenter de supprimer de cette grande table. Pour ces articles, je sais qu'il n'y aurait pas eu d'enregistrement de très grandes tables Table1, Table2, Table3.

Je me demande si cela pourrait être corrigé en passant à:

DELETE d
FROM Table1 d WITH(rowlock)
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId

Je pense que puisque Table1 est une grande table SQL-Server verrouille des pages entières et cette indice ne fera que verrouiller les rangées de verrouillage. Notez que j'ai indexé FK's sur table2Id, table3Id, table4Id et entité.

J'ai activé le traçage comme décrit ici: http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleShooNoting_2c00_-part-.aspx

avec:

DBCC TRACEON (1222, -1)

Vous trouverez ci-dessous la sortie du journal avec "2011-08-29 15: 46: 57.78 SPID15S" Coupé le début de chaque ligne. D'après ce que je vois que deux usp_entityfuldeLete est une impasse sur la même déclaration - une ligne de suppression de la ligne 746946 et une ligne de suppression 628302. Est-ce que je suis correct dans mon analyse de cette sortie? Y a-t-il autre chose qui pourrait aider à prévenir cela?

deadlock-list
 deadlock victim=process3e9ada8
  process-list
   process id=processbaf048 taskpriority=0 logused=20022 waittime=3890 schedulerid=1 kpid=1304 status=suspended spid=59 sbid=0 ecid=1 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0     
    inputbuf
   process id=processbaf588 taskpriority=0 logused=20022 waittime=3906 schedulerid=1 kpid=6244 status=suspended spid=62 sbid=0 ecid=3 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0     
    inputbuf
   process id=process3e9a868 taskpriority=0 logused=580 waitresource=PAGE: 19:1:1942004 waittime=3890 ownerId=1135558120 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.053 XDES=0xf2512b30 lockMode=U schedulerid=3 kpid=8808 status=suspended spid=62 sbid=0 ecid=8 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0     
    inputbuf
   process id=process3e9ada8 taskpriority=0 logused=0 waitresource=PAGE: 19:1:1928384 waittime=3765 ownerId=1135559188 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.263 XDES=0xf2512d70 lockMode=U schedulerid=3 kpid=9196 status=suspended spid=59 sbid=0 ecid=6 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0     
    inputbuf
   process id=process3e9b198 taskpriority=0 logused=20006 waittime=3984 schedulerid=3 kpid=9212 status=suspended spid=59 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 loginname=sa isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0     
    inputbuf
exec dbo.usp_EntityFullDelete 746946,0    
   process id=process46b0da8 taskpriority=0 logused=20006 waittime=4000 schedulerid=4 kpid=6596 status=suspended spid=62 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 loginname=sa isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0     
    inputbuf
exec dbo.usp_EntityFullDelete 628302,0    
   process id=process46b1048 taskpriority=0 logused=0 waitresource=PAGE: 19:1:1942003 waittime=3937 ownerId=1135559188 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.263 XDES=0xd0224ab0 lockMode=U schedulerid=4 kpid=7892 status=suspended spid=59 sbid=0 ecid=8 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0     
    inputbuf
   process id=process46b16d8 taskpriority=0 logused=580 waitresource=PAGE: 19:1:441708 waittime=3937 ownerId=1135558120 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.053 XDES=0xd0224870 lockMode=U schedulerid=4 kpid=6676 status=suspended spid=62 sbid=0 ecid=6 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
    inner join dbo.Table2 orc on orc.id = d.Table2Id
    inner join dbo.Table3 orr on orr.id = orc.Table3Id
    inner join Table4 oeh on oeh.id = orr.Table4Id
    inner join @deleteEntities de on de.id = oeh.EntityId     
     frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0     
    inputbuf
  resource-list
   pagelock fileid=1 pageid=1928384 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockaef9db80 mode=U associatedObjectId=72057595211284480
    owner-list
     owner id=process46b0da8 mode=U
    waiter-list
     waiter id=process3e9ada8 mode=U requestType=wait
   exchangeEvent id=port80128a00 nodeId=22
    owner-list
     owner event=e_waitNone type=producer id=process3e9ada8
     owner event=e_waitNone type=producer id=process46b1048
    waiter-list
     waiter event=e_waitPortClose type=consumer id=processbaf048
   exchangeEvent id=port80128e20 nodeId=6
    owner-list
     owner event=e_waitNone type=producer id=processbaf048
    waiter-list
     waiter event=e_waitPortOpen type=consumer id=process3e9b198
   pagelock fileid=1 pageid=1942004 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockf3d1f080 mode=U associatedObjectId=72057595211284480
    owner-list
     owner id=process3e9b198 mode=U
    waiter-list
     waiter id=process3e9a868 mode=U requestType=wait
   exchangeEvent id=port80128ed0 nodeId=22
    owner-list
     owner event=e_waitNone type=producer id=process46b16d8
     owner event=e_waitNone type=producer id=process3e9a868
    waiter-list
     waiter event=e_waitPortClose type=consumer id=processbaf588
   exchangeEvent id=port80128320 nodeId=6
    owner-list
     owner event=e_waitNone type=producer id=processbaf588
    waiter-list
     waiter event=e_waitPortOpen type=consumer id=process46b0da8
   pagelock fileid=1 pageid=1942003 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockfbcc1680 mode=U associatedObjectId=72057595211284480
    owner-list
     owner id=process46b0da8 mode=U
    waiter-list
     waiter id=process46b1048 mode=U requestType=wait
   pagelock fileid=1 pageid=441708 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockfc628980 mode=U associatedObjectId=72057595211284480
    owner-list
     owner id=process3e9b198 mode=U
    waiter-list
     waiter id=process46b16d8 mode=U requestType=wait
5
Adam Butler

Supprimé ma réponse précédente lorsque j'ai réalisé que la trace montre le parallélisme.

Avec un grand avertissement pour tester cela très très soigneusement, vous risquez d'atténuer les blocages en limitant MaxDop et en ajoutant un indice de mise à jour sur la table1. J'essaye également (selon la suggestion de @ Aaron) exister.

DELETE 
    d
FROM 
    Table1 d WITH (UPDLOCK)
INNER JOIN
    #deleteEntities de
ON  de.id = oeh.EntityId 
WHERE EXISTS
    (
    SELECT
        NULL
    FROM
        dbo.Table2 orc 
    INNER JOIN
        dbo.Table3 orr 
    ON  orr.id = orc.Table3Id
    INNER JOIN 
        dbo.Table4 oeh            
    ON  oeh.id = orr.Table4Id
    WHERE
        oeh.id = de.Table2Id
    ) OPTION (MAXDOP 1, RECOMPILE)

Ce serait l'approche Sledgehammer. Il est probable que vous puissiez éliminer le parallélisme avec l'indexation appropriée mais ne peut en informer que si nous ne voyons qu'un plan d'exécution et des statistiques.

@Deletetentities dans la trace d'impression est un peu "suspect". Vous passez dans un seul identificateur mais avez cette table temporaire là-bas? Optimiseur est susceptible de produire un plan d'exécution qui estime 1 pour cela, de sorte qu'il contient un nombre variable de lignes, je bascule à la table temporaire et à la réception de la force (comme ci-dessus).

4
Mark Storey-Smith

SQL Server peut toujours choisir d'élever le verrouillage de la ligne sur une serrure de table, même si avec (Rowlock) est spécifiée. Cela peut dépendre d'un certain nombre de choses, notamment: nombre de lignes supprimées, nombre de serrures totales acquises par transaction et la pression de mémoire totale de tous les serrures acquises.

Sunil Agarwal a écrit un excellent article décrivant ce processus, qui peut être trouvé ici: http://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/05/17/Lock-escalation.aspx Englisons

Une chose que vous puissiez faire pour atténuer l'impact de ces déclarations de suppression consiste à effectuer les suppressions en morceaux:

WHILE 1 = 1
BEGIN
    DELETE TOP(5000)
    FROM <table>
    WHERE <condition>

    IF @@ROWCOUNT = 0
    BEGIN
        BREAK;
    END
END

Malheureusement, la réponse à votre question initiale est une grosse graisse "cela dépend".

Modifier (ajouter une requête à regarder les informations de verrouillage):

SELECT
    DB_NAME([tl].[resource_database_id]) AS [database_name],
    SCHEMA_NAME([o].[schema_id]) + '.' + [o].[name] AS [object_name],
    [tl].[request_type],
    [tl].[request_mode],
    [tl].[request_status]
FROM sys.dm_exec_sessions AS [es]

    INNER JOIN sys.dm_tran_locks AS [tl]
        ON [es].[session_id] = [tl].[request_session_id]    

        INNER JOIN sys.objects AS [o]
            ON [tl].[resource_associated_entity_id] = [o].[object_id]

WHERE [es].[is_user_process] = 1;

J'espère que cela "presque réponse" aide,

Mat

3
Matt M