SQL Server 2014 CTP1 wprowadza opcje oczekiwania na blokadę o niskim priorytecie do użytku z operacjami indeksowania online i przełącznikami partycji.
Osoby korzystające z zarządzania indeksem online lub partycjonowania indeksu i operacji przełączania partycji w SQL Server 2012 Enterprise Edition mogą w pewnym momencie doświadczyć zablokowania operacji DDL, ponieważ te operacje nadal mają pewne wymagania dotyczące blokowania.
Aby to zilustrować, wyobraź sobie, że wykonuję następującą przebudowę indeksu online z pojedynczą partycją w SQL Server 2014 CTP1:
ZMIEŃ INDEKS [ClusteredIndex_on_ps_ShipDate]ON [dbo].[FactInternetSales]REBUILD PARTITION =(37)With (ONLINE=ON);
Rzućmy też okiem na blokady nabyte i zwolnione podczas tej operacji przebudowy przy użyciu zdarzeń rozszerzonych i następującej definicji sesji (jest to sesja bez celu, a wyniki obserwowałem w okienku „Obserwuj dane na żywo” w SQL Server Management Studio):
UTWÓRZ SESJĘ ZDARZENIA [Online_Index_Rebuild_Locks_Taken] NA SERWERZE DODAJ ZDARZENIE sqlserver.lock_acquired( WHERE ([object_id]=(309576141))),ADD EVENT sqlserver.lock_released( WHERE ([object_id]=(3095 MAX76_141))) 4096 KB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY=30 SECONDS, MAX_EVENT_SIZE=0 KB, MEMORY_PARTITION_MODE=NONE, TRACK_CAUSALITY=OFF, STARTUP_STATE=OFF);GO
Wartość 309576141 reprezentuje identyfikator obiektu tabeli FactInternetSales.
Moja przebudowa indeksu online pojedynczej partycji zajęła 56 sekund, a po jej zakończeniu zobaczyłem następującą aktywność związaną z nabywaniem i zwalnianiem blokady:
Zablokuj aktywność w przypadku odbudowy online pojedynczej partycji
Jak widać z danych wyjściowych, chociaż przebudowa jest operacją online, wiąże się z uzyskaniem blokad w różnych trybach w trakcie cyklu życia operacji. Idealnie czas trwania blokady jest minimalny (na przykład – znacznik czasu jest identyczny dla pierwszego SCH_S
nabyta i zwolniona blokada). Ale nawet przy minimalnej ilości blokowania z pewnością możesz napotkać problemy ze współbieżnością w zależności od transakcji działających w stosunku do przebudowywanego lub przełączanego indeksu.
Wspomniałem na początku tego postu, że Microsoft wprowadził opcje oczekiwania na blokadę o niskim priorytecie dla operacji online i operacji przełączania partycji w SQL Server 2014 CTP1. Jeśli chodzi o przełączniki partycji, wyobraź sobie, że wykonuję następującą operację:
ZMIEŃ TABELĘ [AdventureWorksDW2012].[dbo].[FactInternetSales] ZMIEŃ PARTYCJĘ 37 NA [AdventureWorksDW2012].[dbo].[staging_FactInternetSales];
Aby zobaczyć blokady nabyte i zwolnione dla tej operacji, zmodyfikowałem moją wcześniej zdefiniowaną sesję Extended Event, aby uwzględnić odpowiednie obiekty (tabela źródłowa i docelowa). Widziałem:
Aktywność blokady dla operacji przełączania partycji
Operacja przełączenia na pustą partycję nastąpiła w mniej niż sekundę, ale nadal widzimy, że SCH_S
i SCH_M
blokady były wymagane podczas cyklu życia operacji zarówno w miejscu źródłowym, jak i docelowym (309576141 to FactInternetSales i 398624463 to staging_FactInternetSales).
Tak więc ponownie, chociaż czas trwania blokowania może być bardzo krótki, gdy nie ma jednoczesnych transakcji uzyskujących dostęp do danych obiektów, wiemy, że nie zawsze jest to możliwe, więc nasze operacje odbudowy indeksu online i przełączania partycji mogą rzeczywiście zostać zablokowane.
Tak więc w tej rzeczywistości SQL Server 2014 wprowadza WAIT_AT_LOW_PRIORITY
argument, który można dostosować za pomocą MAX_DURATION
i ABORT_AFTER_WAIT
opcje dla obu ALTER INDEX
i ALTER TABLE
polecenia, których możemy używać zarówno do operacji indeksowania online, jak i przełączania partycji.
Na co nam to pozwala? Przede wszystkim porozmawiajmy o zachowaniu przed SQL Server 2014. Jako przykład wyobraź sobie następującą transakcję otwartą i niezatwierdzoną:
ROZPOCZNIJ TRANSAKCJĘ; USUŃ [dbo].[staging_FactInternetSales];
Gdybym próbował wykonać ALTER TABLE SWITCH
do tabeli staging_FactInternetSales jako miejsce docelowe w osobnej sesji, zostanę zablokowany i żądanie będzie po prostu czekać. Specjalnie dla tego przykładu czekałbym z LCK_M_SCH_M
typ oczekiwania. Po wycofaniu lub zatwierdzeniu transakcji operacja może przejść do przodu i zakończyć.
Teraz, jeśli używam WAIT_AT_LOW_PRIORITY
SQL Server 2014 z MAX_DURATION
i ABORT_AFTER_WAIT
, mogę skorzystać z kilku różnych opcji w zależności od wymagań aplikacji.
MAX_DURATION
pozwala mi określić liczbę minut oczekiwania na odbudowę indeksu w trybie online lub operację przełączania partycji. Jeśli MAX_DURATION
wartość została osiągnięta, możemy ustawić, co stanie się dalej na podstawie ustawienia ABORT_AFTER_WAIT
, który może mieć wartość NONE
, SELF
lub BLOCKERS
:
NONE
oznacza, że operacja indeksowania będzie kontynuowała próbę operacji.SELF
oznacza, że jeśliMAX_DURATION
zostanie osiągnięta, operacja (odbudowa indeksu w trybie online lub przełącznik partycji) zostanie anulowana.- Jeśli
BLOCKERS
jest używany, zabije wszystkie transakcje, które blokują odbudowę indeksu online lub operację przełączania partycji (moim zdaniem nie jest to opcja, którą należy stosować lekko).BLOCKERS
wymaga równieżALTER ANY CONNECTION
pozwolenie na żądanie wydania przebudowy indeksu online lub operacji przełączania partycji.
Poniższe przykłady kodu demonstrują różne odmiany konfiguracji.
Domyślne zachowanie sprzed 2014 r. (czekaj w nieskończoność)
- Wykonanie poniższego spowoduje zachowanie, do którego jesteśmy przyzwyczajeni w wersjach wcześniejszych niż SQL Server 2014 – i nadal może to być to, czego będziesz chcieć lub oczekiwać w niektórych scenariuszach:
ZMIEŃ TABELĘ [AdventureWorksDW2012].[dbo].[FactInternetSales] ZMIEŃ PARTYCJĘ 37 NA [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION =0 MINUT, ABORT_NAFTER)_WAIT>pre>Poczekaj 1 minutę i anuluj operację DDL
- Poniższy przykład czeka przez 1 minutę, jeśli występuje transakcja blokująca i otrzyma „przekroczono limit czasu żądania blokady” dla
SWITCH
operacja po osiągnięciu maksymalnego czasu trwania: ZMIEŃ TABELĘ [AdventureWorksDW2012].[dbo].[FactInternetSales] ZMIEŃ PARTYCJĘ 37 NA [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] Z (WAIT_AT_LOW_PRIORITY (MAX_DURATION =1 MINUTA, ABORT_SELFTER)_WAIT>pre>Poczekaj 1 minutę i zabij blokujących
- Ten przykład czeka przez 1 minutę, jeśli istnieje transakcja blokująca, a następnie zabije transakcje blokujące (w tym źródło lub miejsce docelowe), umożliwiając
SWITCH
operacja do zakończenia. ZMIEŃ TABELĘ [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] ZMIEŃ PARTYCJĘ 37 NA [AdventureWorksDW2012].[dbo].[FactInternetSales] Z (WAIT_AT_LOW_PRIORITY (MAX_DURATION =1 MINUTA, ABORT_AFTER>_WAIT));
W moim przykładzie DELETE
wewnątrz niezatwierdzonej transakcji nie było błędu w moim oknie SQL Server Management Studio, ponieważ nie miałem aktywnie działającej instrukcji, ale próba innej instrukcji w tej sesji zwróciła następujący komunikat o błędzie (ponieważ moja sesja została zabita):
Wystąpił błąd na poziomie transportu podczas wysyłania żądania do serwera. (dostawca:dostawca pamięci współdzielonej, błąd:0 – żaden proces nie znajduje się na drugim końcu potoku.)
Natychmiast zabij blokującego (źródło lub cel dla SWITCH)
- Poniższy przykład jest przykładem natychmiastowego zabicia blokera – a w moim przykładzie zmiana nastąpiła w ciągu sekundy i rzeczywiście sesja, która blokowała, została zabita:
ZMIEŃ TABELĘ [AdventureWorksDW2012].[dbo].[FactInternetSales] ZMIEŃ PARTYCJĘ 37 NA [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] Z (WAIT_AT_LOW_PRIORITY (MAX_DURATION =0 MINUT, ABORT_AFTER_WAIT));Ostatni pozytywny aspekt, o którym chciałem wspomnieć…
Dziennik błędów programu SQL Server zapewnia domyślną inspekcję użycia oczekiwania na blokadę o niskim priorytecie, w tym informacje o
Data 09.10.2013 13:37:15ABORT_AFTER_WAIT
operacja zgodna z informacjami o ofierze:
Dziennik SQL Server (obecnie – 9/10/2013 12:03:00)
Źródło spid51
Wiadomość
Proces Identyfikator 57 został zabity przez instrukcję ABORT_AFTER_WAIT =BLOCKERS DDL na database_id =5, object_id =309576141.Zobaczysz także osobne wpisy dla samej oryginalnej operacji. Na przykład:
Instrukcja ALTER TABLE SWITCH została wykonana w bazie danych 'AdventureWorksDW2012', tabeli 'staging_FactInternetSales' przez nazwę hosta 'WIN-4T7S36VMSD9', identyfikator procesu hosta 1360 z tabelą docelową 'AdventureWorksDW2012.dbo.FactInternetSales' przy użyciu opcji WAIT_AT_AF_LOW_PRIORITY =BLOKERY. Blokujące sesje użytkownika zostaną zabite po maksymalnym czasie oczekiwania.Ten rodzaj rejestrowania jest bardzo przydatny do rozwiązywania problemów i przeprowadzania audytów i cieszę się, że go widzę.