Ich bekomme einen Deadlock, wenn ein SQL Server-Job ausgeführt wird. Der Deadlock tritt bei einer einfachen DELETE-Anweisung auf. Ich hätte gedacht, dass eine SELECT / UPDATE-Abfrage ausgeführt werden muss, um den Deadlock zu verursachen. Aber es sieht so aus, als wäre es DELETE / DELETE Deadlock ...
Was ich suche, ist, warum ich einen DELETE / DELETE-Deadlock bekomme. Es wird (meines Wissens) verschiedene Parameter übergeben.
Irgendwelche Ideen? Vielen Dank.
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
sql-server
deadlock
K09
quelle
quelle
dbo.UserDetailsData
Einbeziehung aller Indizes veröffentlichen? Wissen Sie auch, ob diese Anweisungen mit denselben Parametern aufgerufen werden? Angesichts der Tatsache, dass für beide kein Protokoll verwendet wird, frage ich mich, ob Sie die Anrufe nur serialisieren müssen, weil sie aufeinander treten.Antworten:
Es scheint, dass der Deadlock auftritt, weil:
spid 54 ecid 0
erwirbt eine update (U
) - SeitensperrePAGE: 12:1:5147422
spid 166 ecid 3
fordert eine update (U
) - Seitensperre auf derselben Seite an und wird blockiertspid 54 ecid 2
fordert eine update (U
) - Seitensperre auf derselben Seite an ...Für die Abfrage werden Seiten vorab abgerufen, wobei Aktualisierungssperren von erworben werden
ecid 0
. Das ist Schritt 1 oben. In Schritt 3ecid 2
fordert ein untergeordneter Thread derselben parallelen Abfrage ( ) dieselbe Sperre an. Normalerweise wäre dies kein Problem. SQL Server kenntecid 0
undecid 2
ist Threads desselben übergeordneten Prozesses. Leider steht Schritt 2 dem im Weg und es kommt zu einem Deadlock.Das heißt, Sie sollten sich nicht wirklich darum kümmern, warum der Deadlock auftritt. Die wichtige Frage ist, wie Sie ihn vermeiden können. Die Antwort ist, einen effizienten Zugriffspfad für die bereitzustellen
DELETE
. Die Anweisung muss Zeilen findenWHERE Username = @P1 AND UserDate = @P2
, daher sollten Sie einen Index für diese Spalten haben.Und natürlich haben Sie einen solchen Index. Die eigentliche Frage ist, warum Ihre Probleme aufgetreten sind, nachdem Sie gefilterte Indizes hinzugefügt haben.
Die Antwort darauf ist, dass zusätzliche Spalteninformationen erforderlich sind, um die zu löschenden gefilterten Indexzeilen zu lokalisieren (und ihre Prädikate zu überprüfen). Wenn die Abfrage einen schmalen Ausführungsplan / pro Zeile verwendet , kann die Ausführungsengine die zusätzlichen Spalten im Operator "Clustered Index Delete" nicht wie in einem breiten / pro Index-Plan abrufen.
Weitere Details dazu und ein Beispiel finden Sie in diesem Blogbeitrag .
In diesem Fall müssen die Spalteninformationen aus dem Teil des Plans rechts neben "Clustered Index Delete" stammen. Daher wird ein paralleler Clustered Index-Scan verwendet, und Sie erhalten eine langsame Abfrage mit hohem Deadlock-Potenzial.
Die Antwort lautet: Führen Sie einen der folgenden Schritte aus:
Option 2 wäre meine starke Präferenz.
Option 4 (danke Jack Douglas) hat den Vorteil, Deadlocks zu entfernen und sollte angesichts der disjunkten Natur der Änderungen keine "Aktualisierungskonflikte" verursachen. Es ist jedoch erforderlich, die Snapshot-Isolation auf Datenbankebene zu aktivieren und die Isolationsstufe explizit zu ändern. und wird das zugrunde liegende Problem nicht beheben : Sie werden immer noch mit einem verschwenderischen parallelen Tabellenscan enden, bei dem eine nette Indexsuche das ist, was Sie wirklich wollen.
quelle