Zakleszczenia od zamków na tych samych tabelach tymczasowych w różnych procesach

17

Znalazłem impas, który wydaje się pokazywać coś, co moim zdaniem było niemożliwe. W impasie występują dwa procesy:

1. process8cf948 SPID 63

  • Wykonanie ALTER TABLE w tabeli tymczasowej #PB_Cost_Excp_Process_Invoices_Work.

  • Posiada blokadę IX w tabeli #PB_Cost_Excp_Process_Invoices_Work z identyfikatorem obiektu 455743580

2. process4cb3708 SPID 72

  • Występowanie w AKTUALIZACJI na tymczasowym stole #PB_Cost_Excp_Process_Invoices_Work, który ma być własną unikalną kopią tabeli.

  • Jest właścicielem blokady Sch-M na #PB_Cost_Excp_Process_Invoices_Work z tym samym identyfikatorem obiektu 455743580 !

To ma być niemożliwe. Czy coś brakuje? Czy stół #Temporary naprawdę został ponownie wykorzystany między tymi dwoma identyfikatorami SPID?

Dotyczy to SQL Server 2008 R2 z dodatkiem Service Pack 2 z aktualizacją zbiorczą 1 (wersja 10.50.4260).

Pełny niezmieniony ślad impasu znajduje się poniżej. Zwróć uwagę, jak oba procesy działają na tym samym identyfikatorze obiektu o tej samej nazwie tabeli # 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

AKTUALIZACJA

Maszyna, o której mowa, pokazuje 16 procesorów w Menedżerze zadań i Menedżerze urządzeń, więc partycjonowanie blokady jest włączone, a dwie blokady znajdują się na różnych partycjach blokady. Nie wiem, czy partycjonowanie blokady jest tutaj przyczyną, czy nie.

Ten intrygujący post znalazłem również na blogu inżynierów programu CSS SQL Server .

AKTUALIZACJA 2

Tabele tymczasowe są usuwane na końcu każdej procedury składowanej. Są one tworzone za pomocą wzoru create #table, modyfikuj schemat, wstawiaj, aktualizuj, zaznaczaj, a następnie upuszczaj. Istnieje wiele punktów wejścia do wspólnej procedury korzystającej z tej tabeli temp, więc mamy centralny proc, który konfiguruje kolumny potrzebne do wywołania wspólnego proc. W przeciwnym razie musielibyśmy powielić tę samą definicję # tabeli we wszystkich procesach punktu wejścia.

Proces jest często wywoływany z wielu aplikacji klienckich. Niektóre aplikacje klienckie wywołują ten proces z wielu wątków. Inni uruchamiają go pojedynczo. Pomyśl o oprogramowaniu inwentaryzacyjnym / księgowym, w którym biuro domowe przetwarza dane dla tysięcy sklepów równolegle, podczas gdy sklepy same wykonują ten sam proces. Jeśli więc jest to rzadki problem przy włączonym blokowaniu partycjonowania, nie będzie tak rzadko w naszych większych bazach danych klientów.

AKTUALIZACJA 3 - 2012-12-19

Inny klient ma ten sam problem w wersji SQL Server 2012 11.0.2100. W opisach aktualizacji zbiorczej nie widziałem wzmianki o rozwiązaniu tego problemu. Badanie

AKTUALIZACJA 4 - 2013-02-13

Firma Microsoft wydała poprawkę dotyczącą tego błędu w następujących aktualizacjach:

Paul Williams
źródło
@AaronBertrand: Nie, nie chcemy buforowania #temp table. To byłoby wystarczająco złe w tym samym połączeniu - a tym bardziej ponowne wykorzystanie między procesami. Nie mam pliku .xdl, tylko informacje o flagi śledzenia 1222.
Paul Williams
Po zakończeniu pracy wyraźnie upuszczamy te #temp tabele.
Paul Williams,
2
Nadal sugerowałbym przechwycenie i opublikowanie gdzieś pliku .xdl, aby inni mogli przyjrzeć się bliżej - będzie on miał znacznie lepsze szczegóły.
Aaron Bertrand
2
Mogę potwierdzić, że dotyczy to partycjonowania blokady. Te posty zawierają szczegółowe informacje na temat analizy zakleszczeń związanych z partycjami blokad i ze względu na nie. bit.ly/Ruzmym bit.ly/W7yuRK Ale nie wiem, dlaczego obie sesje opublikowały ten sam identyfikator obiektu.
Roji P Thomas
@SQLKiwi Dziękujemy za spojrzenie na problem! Nie myślałem o blokowaniu skrótów zasobów. Biorąc pod uwagę, że jest to identyfikator obiektu, podejrzewam, że tak nie jest, ale po prostu zgaduję. Klient zgłaszał nam impasy od kilku dni. Mam tylko jeden dzień śledzenia impasu, ale założę się, że to impas, którego doświadczali. Otwieramy bilet pomocy technicznej w firmie Microsoft, aby pomóc nam to rozwiązać. Zaktualizuję to pytanie, gdy dowiem się więcej.
Paul Williams

Odpowiedzi:

4

Otworzyliśmy sprawę z Microsoft dotyczącą tego problemu. Microsoft potwierdził, że ten błąd dotyczy także SQL Server 2012. Planują wydanie poprawki w SQL Server 2012 Service Pack 2 (nie wydany w czasie, gdy pisałem tę odpowiedź).

Dopóki Microsoft nie wyda tego dodatku Service Pack, użytkownicy programu SQL Server 2012 mogą obejść ten problem, wyłączając blokowanie partycji za pomocą flagi śledzenia 1229 .

Uwaga: ten problem dotyczy tylko komputerów z 16 lub więcej procesorami.

Więcej informacji na temat partycjonowania blokady

Moje podziękowania dla wsparcia Microsoft! Byli bardzo szybcy i pomocni.

AKTUALIZACJA

Błąd został naprawiony w SQL Server 2012 Zbiorcza aktualizacja 2 dla SQL Server 2012 SP 1 .

Paul Williams
źródło