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

Eskalacja blokady serwera SQL

Wprowadzenie

Relacyjne bazy danych są zgodne z właściwościami ACID w sposobie implementacji transakcji — atomowość, spójność, izolacja i trwałość. Izolacja jest konieczna, aby zapewnić, że wiele transakcji nie może spowodować zmian w danych i pozostawić niespójne wyniki. Aby zagwarantować, że operacje pozostaną odizolowane, SQL Server stosuje mechanizmy blokowania.

Tryby blokady i hierarchia

W grę wchodzi mechanizm kontroli współbieżności w SQL Server. Aby zoptymalizować wydajność pod względem oczekiwania na blokadę, zakleszczeń itp., musisz podjąć decyzję opartą na konkretnym scenariuszu.

W SQL Server blokady mogą być utrzymywane na różne sposoby i na kilku poziomach szczegółowości. Tryby blokady to konkretne sposoby, a ich poziomy to hierarchia blokady.

Rysunek 1 przedstawia tryby blokady dostępne w SQL Server dla domyślnego poziomu izolacji transakcji (READ COMMITTED):

Omówienie eskalacji blokady

SQL Server może blokować zasoby na kilku poziomach. Zależy to od najbardziej efektywnych działań w zależności od charakteru obciążenia pracą. Tabela 1 pokazuje zasoby, które można zablokować.

  • Blokady na bardziej szczegółowym poziomie (np. blokady na poziomie wiersza) umożliwiają wyższą współbieżność i mniej blokowania.
  • Blokady na wyższym poziomie (np. Blokada na poziomie tabeli) zmniejszają współbieżność. Mogą powodować większe blokowanie, w zależności od tego, jak długo trwa rzeczywiste oświadczenie.

SQL Server wybiera niezbędny poziom blokowania zgodnie z wewnętrznymi metrykami.

Eskalacja blokady ma miejsce, gdy blokada jest konwertowana z drobniejszego poziomu szczegółowości na gorszy.

Np. zamiana blokady wiersza na blokadę tabeli (patrz Tabela 1).

Zasób Opis
RID Identyfikator wiersza używany do blokowania pojedynczego wiersza w stercie.
KLUCZ Blokada wiersza w indeksie używana do ochrony zakresów kluczy w transakcjach podlegających serializacji.
STRONA Strona o wielkości 8 kilobajtów (KB) w bazie danych, taka jak strony danych lub indeksu.
ZAKRES Ciągła grupa ośmiu stron, takich jak strony danych lub indeksu.
HoBT Karta lub B-drzewo. Blokada chroni B-drzewo (indeks) lub strony danych sterty w tabeli, która nie ma indeksu klastrowego.
TABELA Cała tabela, w tym wszystkie dane i indeksy.
PLIK Plik bazy danych.
APLIKACJA Zasób określony przez aplikację.
METADANE Blokady metadanych.
ALLOCATION_UNIT Jednostka alokacji.
BAZA DANYCH Cała baza danych.

Uzasadnienie eskalacji blokady

Blokady w SQL Server mogą być dość drogie. Dla każdej blokady uzyskanej przez Menedżera blokad SQL Server musi zarezerwować pamięć — 64 bajty lub 128 bajtów. Kwota zależy od tego, czy mamy do czynienia odpowiednio z systemem 32-bitowym czy 64-bitowym.

Wraz ze wzrostem liczby blokad wierszy w tabeli SQL Server musi nabywać coraz więcej pamięci. W związku z tym inne procesy głodują, z braku pamięci.

Sensowne jest przekształcenie blokad wierszy i blokad stron w blokadę na poziomie pojedynczej tabeli (obiektu). Dzieje się tak, gdy liczba blokad dla tej tabeli przekracza 5000.

Kompromis ma miejsce, gdy cała tabela nie jest już dostępna dla innych sesji w procesie transakcji.

Wykazanie eskalacji blokady

Możemy zademonstrować eskalację blokady za pomocą kodu z Listingu 1.

Najpierw trochę opiszmy tabelę. Produkcja.ProduktyI to stosunkowo mały stół z około 7777 rzędami. Elementy budynku to ten sam zestaw 77 rzędów zduplikowanych 101 razy. Kod z Listingu 1 składa się z trzech wersji tego samego wyciągu aktualizującego, z których każda jest zawarta w transakcji.

-- Listing 1: Demonstrating Lock Escalation

-- Update very few rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK 

Dla większej jasności podzielimy zawartość Listingu 1.

Wcześniej spójrzmy na Listing 2 – zapytanie wyświetlające blokady znajdujące się w bazie danych TSQLV4.

Naszym pierwszym działaniem jest wykonanie Listingu 1a. Następnie używamy Listingu 2, aby sprawdzić, jak Menedżer blokad wykonuje blokowanie w scenariuszu. Listing 1a wykonujemy bez wydawania instrukcji rollback. W ten sposób zachowujemy blokady wystarczająco długo, aby zapytanie z Listingu 2 mogło je przechwycić.

-- Listing 1a: Demonstrating Lock Escalation
-- Update very few rows

BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Listing 2: Displaying Locks Held in Database TSQLV4

USE TSQLV4
GO
SELECT 
resource_type
, DB_NAME (resource_database_id) database_name
--, OBJECT_NAME(resource_associated_entity_id) resource_name
, request_mode
, request_type
, request_status
, request_reference_count
, request_session_id
, resource_associated_entity_id
, OBJECT_NAME(resource_associated_entity_id) [object_name] --small obj ids
, getuser.login_name
FROM sys.dm_tran_locks
CROSS APPLY dmv.dbo.getuser(request_session_id) as getuser
WHERE DB_NAME (resource_database_id)='TSQLV4';

Kiedy uruchamiamy zapytanie z Listingu 1a, a następnie sprawdzamy blokady za pomocą zapytania z Listingu 2, SQL Server zwraca wynik pokazany na Rysunku 2.

404 wiersze w tabeli mają cena jednostkowa=’18.00’ . Menedżer zamków blokuje te rzędy wraz z innymi zamkami na dowolnym wymaganym poziomie. Powoduje to zwiększenie liczby wierszy na Rysunku 2 do 467.

-- Listing 1b: Demonstrating Lock Escalation
-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

Podobne zachowanie obserwujemy, gdy wykonujemy zapytanie z Listingu 1b. Tym razem mamy do czynienia z 4406 rzędami. Odzwierciedla liczbę wierszy w tabeli Produkcja.ProduktI mający cenę jednostkową>18,00.

-- Listing 1c: Demonstrating Lock Escalation
-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK

Kiedy pójdziemy dalej i wykonamy kod z Listingu 1c, zobaczymy inne zachowanie (patrz Rysunek 4).

Listing 1c próbuje zaktualizować wszystkie 7777 wierszy w tabeli Production.ProductI. SQL Server określa, że ​​blokowanie tak wielu wierszy nie jest już skuteczne, aby zagwarantować izolację. Zamiast tego cały stół jest zablokowany.

Więcej informacji o eskalacji blokady

Blokada tabeli oznacza, że ​​żadna inna sesja nie może modyfikować swoich wierszy na czas trwania transakcji, co może się zdarzyć nawet wtedy, gdy sesja blokująca nie manipuluje wszystkimi wierszami w tabeli.

Warto również wspomnieć, że inne czynniki mogą wpływać na sposób uzyskiwania i eskalacji blokad w SQL Server. To są flagi skonfigurowanego poziomu izolacji, indeksowania i śledzenia.

Flagi śledzenia T1211 i T1224 mogą zastosować do całkowitego wyłączenia blokady eskalacji. Eskalację blokady można również wyłączyć i włączyć dla określonej tabeli za pomocą następującego kodu:

-- Listing 5: Disable and Enable Lock Escalation

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=DISABLE);

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=TABLE);

Można to zrobić, aby zmniejszyć blokowanie związane z blokowaniem całej tabeli. Ze względu na wpływ na pamięć, należy rozważyć to jako środek tymczasowy.

Wniosek

SQL Server używa funkcji Lock Escalation do kontrolowania wpływu bardziej szczegółowego blokowania na zasoby serwera. Aby wyświetlić sposób występowania tych blokad – blokady wierszy, blokady stron, blokady obiektów itp. – odpytaj widok zarządzania dynamicznego sys.dm_tran_locks. Zawiera wiele informacji o blokowaniu, poza eskalacją blokady.

Chociaż możliwe jest manipulowanie zachowaniem Menedżera zamków, ważne jest, aby robić to z dużą ostrożnością. Istotne jest również, aby znać dokładny wpływ na wydajność wszelkich wysiłków skierowanych na wprowadzenie takich modyfikacji.

Referencje

  1. Korotkevitch, D., 2016. Wewnętrzne elementy Pro SQL Server. Floryda:Dmitrij Korotkewicz
  2. Zablokuj scenariusze za pomocą Sys.dm_tran_locks
  3. Przewodnik dotyczący blokowania transakcji i wersjonowania wierszy


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy można używać agregatów zdefiniowanych przez użytkownika (clr) z funkcjami okna (over)?

  2. Wgląd w unikalne ograniczenia SQL Server

  3. Jak przekazać parametry wartości tabeli do procedury składowanej z kodu .net?

  4. Wyszukiwanie rozmyte w programie SQL Server z wartością procentową dopasowania

  5. Jakiś sposób na wstawienie lub aktualizację SQLBulkCopy, jeśli istnieje?