Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Badanie opcji oczekiwania na blokadę o niskim priorytecie w programie SQL Server 2014 CTP1

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śli MAX_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):

      Msg 233, Poziom 20, Stan 0, Wiersz 3
      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 ABORT_AFTER_WAIT operacja zgodna z informacjami o ofierze:

Data 09.10.2013 13:37:15
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ę.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Domyślna kolejność wierszy w zapytaniu SELECT — SQL Server 2008 vs SQL 2012

  2. Jak odszyfrować hasło z serwera SQL?

  3. Jak usunąć z bazy danych datę i godzinę, która może mieć wartość null

  4. Jak wstawić listę C# do bazy danych za pomocą Dapper.NET?

  5. Odroczone ograniczenia w SQL Server