Deadlocks aufgrund von Sperren für dieselben temporären Tabellen in unterschiedlichen Prozessen

17

Ich habe eine Sackgasse gefunden, die etwas zu zeigen scheint, was ich für unmöglich hielt. Es gibt zwei Prozesse, die am Deadlock beteiligt sind:

1. process8cf948 SPID 63

  • Durchführen einer ALTER TABLE für die temporäre Tabelle #PB_Cost_Excp_Process_Invoices_Work.

  • Besitzt die IX-Sperre für die Tabelle #PB_Cost_Excp_Process_Invoices_Work mit der Objekt-ID 455743580

2. process4cb3708 SPID 72

  • Ausführung in UPDATE für die temporäre Tabelle #PB_Cost_Excp_Process_Invoices_Work, die eine eigene eindeutige Kopie der Tabelle sein soll.

  • Besitzt die Sch-M-Sperre für #PB_Cost_Excp_Process_Invoices_Work mit derselben Objekt-ID 455743580 !

Das soll unmöglich sein. Vermisse ich etwas? Wurde eine temporäre Tabelle zwischen diesen beiden SPIDs wirklich wiederverwendet?

Dies ist SQL Server 2008 R2 Service Pack 2 mit kumulativem Update 1 (Version 10.50.4260).

Die vollständige unveränderte Deadlock-Spur befindet sich unten. Beachten Sie, wie beide Prozesse auf derselben Objekt-ID mit demselben Tabellennamen arbeiten # PB_Cost_Excp_Process_Invoices_Work_SNIP_0000000D8519:

12/14/2012 13:46:03,spid23s,Unknown,waiter id=process8cf948 mode=X requestType=wait
12/14/2012 13:46:03,spid23s,Unknown,waiter-list
12/14/2012 13:46:03,spid23s,Unknown,owner id=process4cb3708 mode=Sch-M
12/14/2012 13:46:03,spid23s,Unknown,owner-list
12/14/2012 13:46:03,spid23s,Unknown,objectlock lockPartition=0 objid=455743580 subresource=FULL dbid=2 objectname=tempdb.dbo.#PB_Cost_Excp_Process_Invoices_Work_________________________________________________________________________________0000000D8519 id=lock371705d00 mode=Sch-M associatedObjectId=455743580
12/14/2012 13:46:03,spid23s,Unknown,waiter id=process4cb3708 mode=Sch-M requestType=wait
12/14/2012 13:46:03,spid23s,Unknown,waiter-list
12/14/2012 13:46:03,spid23s,Unknown,owner id=process8cf948 mode=IX
12/14/2012 13:46:03,spid23s,Unknown,owner-list
12/14/2012 13:46:03,spid23s,Unknown,objectlock lockPartition=3 objid=455743580 subresource=FULL dbid=2 objectname=tempdb.dbo.#PB_Cost_Excp_Process_Invoices_Work_________________________________________________________________________________0000000D8519 id=lock3139b4780 mode=IX associatedObjectId=455743580
12/14/2012 13:46:03,spid23s,Unknown,resource-list
12/14/2012 13:46:03,spid23s,Unknown,Proc [Database Id = 8 Object Id = 1857974987]
12/14/2012 13:46:03,spid23s,Unknown,inputbuf
12/14/2012 13:46:03,spid23s,Unknown,EXEC PB_ProcessExc_Costs_Submit_SP @SiteKey, @PWDate
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.DR_SubmitPaperwork_SP line=174 stmtstart=12912 stmtend=13018 sqlhandle=0x03000800cb72be6e500434018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,EXEC PB_ProcessExc_Costs_Create_SP

    -- Clean up work table
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_Submit_SP line=138 stmtstart=11890 stmtend=12012 sqlhandle=0x03000800428c1f1950f833018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,UPDATE #PB_Cost_Excp_Process_Invoices_Work
    SET PBCEPrcInv_RtlPkg_Item_Quantity = RtlPkg_Item_Quantity
    FROM #PB_Cost_Excp_Process_Invoices_Work
        INNER JOIN Item_Packages (NOLOCK)
            ON PBCEPrcInv_ItemPkg_Key = ItemPkg_Key
        INNER JOIN Retail_Packages (NOLOCK)
            ON ItemPkg_RtlPkg_Key = RtlPkg_Key

    -- Lookup pricebook cost
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_Create_SP line=25 stmtstart=2394 stmtend=3050 sqlhandle=0x030008003a082846321f46018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,executionStack
12/14/2012 13:46:03,spid23s,Unknown,process id=process8cf948 taskpriority=0 logused=0 waitresource=OBJECT: 2:455743580:0  waittime=3739 ownerId=707053534 transactionname=UPDATE lasttranstarted=2012-12-14T13:45:59.327 XDES=0x3c4502930 lockMode=X schedulerid=4 kpid=7276 status=suspended spid=72 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2012-12-14T13:45:58.337 lastbatchcompleted=2012-12-14T13:45:58.337 clientapp=PDI WCF Services - pdidb01-PDIMaster.cfg hostname=PDIWEB01 hostpid=2084 loginname=pdiuser isolationlevel=read committed (2) xactid=707053534 currentdb=8 lockTimeout=4294967295 clientoption1=673316896 clientoption2=128568
12/14/2012 13:46:03,spid23s,Unknown,Proc [Database Id = 8 Object Id = 1857974987]
12/14/2012 13:46:03,spid23s,Unknown,inputbuf
12/14/2012 13:46:03,spid23s,Unknown,EXEC PB_ProcessExc_Costs_Submit_SP @SiteKey, @PWDate
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.DR_SubmitPaperwork_SP line=174 stmtstart=12912 stmtend=13018 sqlhandle=0x03000800cb72be6e500434018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,EXEC dbo.PB_ProcessExc_Costs_CreateInvoiceWorkTable_SP
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_Submit_SP line=58 stmtstart=5782 stmtend=5894 sqlhandle=0x03000800428c1f1950f833018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,ALTER TABLE #PB_Cost_Excp_Process_Invoices_Work DROP COLUMN PBCEPrcInv_Filler
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_CreateInvoiceWorkTable_SP line=50 stmtstart=5382 stmtend=5538 sqlhandle=0x0300080025d75a14ffff4701969f00000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,executionStack
12/14/2012 13:46:03,spid23s,Unknown,process id=process4cb3708 taskpriority=0 logused=0 waitresource=OBJECT: 2:455743580:3  waittime=3739 ownerId=707052778 transactionname=ALTER TABLE lasttranstarted=2012-12-14T13:45:58.517 XDES=0x5f48bce80 lockMode=Sch-M schedulerid=6 kpid=7212 status=suspended spid=63 sbid=0 ecid=0 priority=0 trancount=1 lastbatchstarted=2012-12-14T13:45:58.513 lastbatchcompleted=2012-12-14T13:45:58.513 clientapp=PDI WCF Services - pdidb01-PDIMaster.cfg hostname=PDIWEB01 hostpid=2084 loginname=pdiuser isolationlevel=read committed (2) xactid=707052778 currentdb=2 lockTimeout=4294967295 clientoption1=673316896 clientoption2=128568
12/14/2012 13:46:03,spid23s,Unknown,process-list
12/14/2012 13:46:03,spid23s,Unknown,deadlock victim=process4cb3708
12/14/2012 13:46:03,spid23s,Unknown,deadlock-list

AKTUALISIEREN

Der betreffende Computer zeigt 16 Prozessoren im Task-Manager und im Geräte-Manager an, sodass die Sperrenpartitionierung aktiviert ist und sich die beiden Sperren auf verschiedenen Sperrenpartitionen befinden. Ich weiß nicht, ob die Sperrenpartitionierung hier einen Beitrag leistet oder nicht.

Ich habe diesen interessanten Beitrag auch im CSS SQL Server Engineers-Blog gefunden .

UPDATE 2

Die temporären Tabellen werden am Ende jeder gespeicherten Prozedur gelöscht. Sie werden mit dem Muster create #table erstellt, das Schema geändert, eingefügt, aktualisiert, ausgewählt und dann gelöscht. Es gibt mehrere Einstiegspunkte für eine allgemeine Prozedur, die diese temporäre Tabelle verwendet. Wir haben also einen zentralen Proc, der die Spalten einrichtet, die zum Aufrufen des allgemeinen Proc erforderlich sind. Andernfalls müssten wir die gleiche #table-Definition in allen Einstiegspunkt-Prozessen replizieren.

Der Prozess wird häufig von mehreren Clientanwendungen aufgerufen. Einige Clientanwendungen rufen diesen Prozess von mehreren Threads aus auf. Andere führen es einzeln aus. Denken Sie an eine Inventar- / Buchhaltungssoftware, bei der das Home Office Daten für Tausende von Filialen parallel verarbeitet, während die Filialen selbst denselben Prozess ausführen. Wenn dies also ein seltenes Problem ist, wenn die Sperrenpartitionierung aktiviert ist, wird es in unseren größeren Kundendatenbanken nicht so selten vorkommen.

UPDATE 3 - 2012-12-19

Ein anderer Kunde hat das gleiche Problem mit SQL Server 2012 Build 11.0.2100. In den Beschreibungen der kumulativen Updates wurde kein Fix für dieses Problem erwähnt. Recherchieren.

UPDATE 4 - 2013-02-13

Microsoft hat das Update für diesen Fehler in den folgenden Updates veröffentlicht:

Paul Williams
quelle
@AaronBertrand: Nein, wir wollen kein # temporäres Tabellen-Caching. Das wäre bei derselben Verbindung schon schlimm genug - geschweige denn, zwischen Prozessen wiederverwendet zu werden. Ich habe keine .xdl-Datei, nur das Trace-Flag 1222 info.
Paul Williams
Wir löschen diese # temporären Tabellen explizit, wenn wir damit fertig sind.
Paul Williams
2
Ich würde immer noch vorschlagen, die .xdl-Datei irgendwo zu erfassen und zu veröffentlichen, damit andere sie genauer betrachten können - sie wird viel detaillierter sein.
Aaron Bertrand
2
Ich kann bestätigen, dass es sich um eine Sperrenpartitionierung handelt. Diese Posts enthalten einige Details zum Analysieren von Deadlocks, die Sperrpartitionen betreffen und auf diese zurückzuführen sind. bit.ly/Ruzmym bit.ly/W7yuRK Aber ich weiß nicht, warum beide Sitzungen dieselbe ObjectID gepostet haben.
Roji P Thomas
@SQLKiwi Vielen Dank, dass Sie sich das Problem angesehen haben! Ich habe nicht über das Sperren von Ressourcen-Hashing nachgedacht. Angesichts der Tatsache, dass es sich um eine Objekt-ID handelt, vermute ich, dass dies nicht der Fall ist, aber ich rate nur. Der Kunde meldet uns seit mehreren Tagen Deadlocks. Ich habe nur einen Tag Deadlock Tracing, aber ich wette, dies ist der Deadlock, den sie erlebt haben. Wir eröffnen ein Support-Ticket bei Microsoft, um es herauszufinden. Ich werde diese Frage aktualisieren, sobald ich mehr erfahre.
Paul Williams

Antworten:

4

Wir hatten einen Fall mit Microsoft in Bezug auf dieses Problem eröffnet. Microsoft hat bestätigt, dass dieser Fehler auch SQL Server 2012 betrifft. Sie planen, das Update in SQL Server 2012 Service Pack 2 (das zum Zeitpunkt des Schreibens dieser Antwort noch nicht veröffentlicht wurde) zu veröffentlichen.

Bis zur Veröffentlichung dieses Service Packs durch Microsoft können SQL Server 2012-Benutzer das Problem umgehen, indem sie die Sperrenpartitionierung über das Ablaufverfolgungsflag 1229 deaktivieren .

Beachten Sie, dass dieses Problem nur für Computer mit 16 oder mehr Prozessoren gilt.

Weitere Informationen zur Sperrenpartitionierung

Mein Dank geht an den Microsoft Support! Sie waren sehr schnell und hilfsbereit.

AKTUALISIEREN

Der Fehler wurde in SQL Server 2012 Cumulative Update 2 für SQL Server 2012 SP 1 behoben .

Paul Williams
quelle