W tym poście omówimy mechanizm blokowania SQL Server i sposób monitorowania blokowania SQL Server za pomocą standardowych dynamicznych widoków zarządzania SQL Server. Zanim zaczniemy wyjaśniać architekturę blokad SQL Server, poświęćmy chwilę na opisanie, czym jest baza danych ACID (Atomicity, Consistency, Isolation, and Durability). Baza danych ACID może być wyjaśniona jako teoria baz danych. Jeśli baza danych nazywa się relacyjną bazą danych, musi spełniać wymagania dotyczące atomowości, spójności, izolacji i trwałości. Teraz pokrótce wyjaśnimy te wymagania.
Atomowość :Odzwierciedla zasadę niepodzielności, którą określamy jako główną cechę procesu transakcyjnego. Bloku transakcji nie można pozostawić bez nadzoru. Połowa pozostałego bloku transakcji powoduje niespójność danych. Albo cała transakcja jest wykonywana, albo transakcja wraca do początku. Oznacza to, że wszystkie zmiany wprowadzone przez transakcję są cofane i przywracane do poprzedniego stanu.
Spójność :Istnieje reguła, która określa podstrukturę reguły niepodzielności. Dane transakcyjne muszą zapewniać spójność. Oznacza to, że jeśli operacja aktualizacji jest wykonywana w transakcji, albo wszystkie pozostałe transakcje muszą zostać wykonane, albo operacja aktualizacji musi zostać anulowana. Te dane są bardzo ważne pod względem spójności.
Izolacja :To jest pakiet żądań dla każdej bazy danych transakcji. Zmiany wprowadzone przez pakiet żądania muszą być widoczne dla innej transakcji przed jej zakończeniem. Każda transakcja musi być przetwarzana osobno. Wszystkie transakcje muszą być widoczne dla innej transakcji po ich wystąpieniu.
Trwałość: Transakcje mogą wykonywać złożone operacje na danych. Aby wszystkie te transakcje były zabezpieczone, muszą być odporne na błąd transakcyjny. Problemy systemowe, które mogą wystąpić w SQL Server, powinny być przygotowane i odporne na awarię zasilania, system operacyjny lub inne błędy spowodowane przez oprogramowanie.
Transakcja: Transakcja to najmniejszy stos procesu, którego nie można podzielić na mniejsze części. Ponadto, pewna grupa procesów transakcyjnych może być wykonywana sekwencyjnie, ale jak wyjaśniliśmy w zasadzie Atomity, jeśli chociaż jedna z transakcji się nie powiedzie, wszystkie bloki transakcji zakończą się niepowodzeniem.
Zablokuj: Blokada to mechanizm zapewniający spójność danych. SQL Server blokuje obiekty po rozpoczęciu transakcji. Po zakończeniu transakcji SQL Server zwalnia zablokowany obiekt. Ten tryb blokady można zmienić zgodnie z typem procesu SQL Server i poziomem izolacji. Te tryby blokady to:
Zablokuj hierarchię: SQL Server ma hierarchię blokad, która nabywa obiekty blokujące w tej hierarchii. Baza danych znajduje się na szczycie hierarchii, a wiersz na dole. Poniższy obraz ilustruje hierarchię blokad SQL Server.
Blokady współdzielone (S): Ten typ blokady występuje, gdy obiekt musi zostać odczytany. Ten typ blokady nie sprawia większego problemu.
Ekskluzywne (X) blokady: Wystąpienie tego typu blokady ma na celu uniemożliwienie innym transakcjom modyfikacji lub dostępu do zablokowanego obiektu.
Aktualizuj blokady (U): Ten typ zamka jest podobny do zamka ekskluzywnego, ale ma pewne różnice. Operację aktualizacji możemy podzielić na różne fazy:fazę odczytu i fazę zapisu. Podczas fazy odczytu SQL Server nie chce, aby inne transakcje miały dostęp do tego obiektu, aby zostały zmienione. Z tego powodu SQL Server używa blokady aktualizacji.
Blokady intencji: Blokada intencji występuje, gdy program SQL Server chce uzyskać blokadę współdzieloną (S) lub blokadę wyłączną (X) na niektórych zasobach znajdujących się niżej w hierarchii blokad. W praktyce, gdy SQL Server uzyskuje blokadę na stronie lub wierszu, w tabeli wymagana jest blokada zamierzona.
Po tych wszystkich krótkich wyjaśnieniach postaramy się znaleźć odpowiedź, jak rozpoznać zamki. SQL Server oferuje wiele dynamicznych widoków zarządzania umożliwiających dostęp do metryk. Aby zidentyfikować blokady SQL Server, możemy użyć sys.dm_tran_locks pogląd. W tym widoku możemy znaleźć wiele informacji o aktualnie aktywnych zasobach menedżera blokad.
W pierwszym przykładzie utworzymy tabelę demonstracyjną, która nie zawiera żadnych indeksów, i spróbujemy ją zaktualizować.
CREATE TABLE TestBlock (Id INT , Nm VARCHAR(100)) INSERT INTO TestBlock values(1,'CodingSight') In this step, we will create an open transaction and analyze the locked resources. BEGIN TRAN UPDATE TestBlock SET Nm='NewValue_CodingSight' where Id=1 select @@SPID
Teraz sprawdzimy widok sys.dm_tran_lock.
select * from sys.dm_tran_locks WHERE request_session_id=74
Ten widok zwraca wiele informacji o aktywnych zasobach blokady. Nie jest jednak możliwe zrozumienie niektórych danych z tego punktu widzenia. Z tego powodu musimy dołączyć do sys.dm_tran_locks widok do innych widoków.
SELECT dm_tran_locks.request_session_id, dm_tran_locks.resource_database_id, DB_NAME(dm_tran_locks.resource_database_id) AS dbname, CASE WHEN resource_type = 'OBJECT' THEN OBJECT_NAME(dm_tran_locks.resource_associated_entity_id) ELSE OBJECT_NAME(partitions.OBJECT_ID) END AS ObjectName, partitions.index_id, indexes.name AS index_name, dm_tran_locks.resource_type, dm_tran_locks.resource_description, dm_tran_locks.resource_associated_entity_id, dm_tran_locks.request_mode, dm_tran_locks.request_status FROM sys.dm_tran_locks LEFT JOIN sys.partitions ON partitions.hobt_id = dm_tran_locks.resource_associated_entity_id LEFT JOIN sys.indexes ON indexes.OBJECT_ID = partitions.OBJECT_ID AND indexes.index_id = partitions.index_id WHERE resource_associated_entity_id > 0 AND resource_database_id = DB_ID() and request_session_id=74 ORDER BY request_session_id, resource_associated_entity_id
Na powyższym obrazku możesz zobaczyć zablokowane zasoby. SQL Server uzyskuje wyłączną blokadę w tym wierszu. (RID :identyfikator wiersza używany do zablokowania pojedynczego wiersza w stercie) W tym samym czasie SQL Server uzyskuje zamierzoną blokadę na wyłączność na stronie i TestBlock stół. Oznacza to, że żaden inny proces nie może odczytać tego zasobu, dopóki SQL Server nie zwolni blokad. To jest podstawowy mechanizm blokady w SQL Server.
Teraz wypełnimy niektóre syntetyczne dane w naszej tabeli testowej.
TRUNCATE TABLE TestBlock DECLARE @K AS INT=0 WHILE @K <8000 BEGIN INSERT TestBlock VALUES(@K, CAST(@K AS varchar(10)) + ' Value' ) SET @[email protected]+1 END After completing this step, we will run two queries and check the sys.dm_tran_locks view. BEGIN TRAN UPDATE TestBlock set Nm ='New_Value' where Id<5000
W powyższym zapytaniu SQL Server uzyskuje wyłączną blokadę w każdym wierszu. Teraz uruchomimy kolejne zapytanie.
BEGIN TRAN UPDATE TestBlock set Nm ='New_Value' where Id<7000
W powyższym zapytaniu SQL Server tworzy blokadę na wyłączność w tabeli, ponieważ SQL Server próbuje uzyskać wiele blokad RID dla tych wierszy, które zostaną zaktualizowane. Ten przypadek powoduje duże zużycie zasobów w silniku bazy danych. Dlatego SQL Server automatycznie przenosi tę blokadę na wyłączność do obiektu wyższego poziomu, który znajduje się w hierarchii blokad. Definiujemy ten mechanizm jako Lock Escalation. Eskalację blokady można zmienić na poziomie stołu.
ALTER TABLE XX_TableName SET ( LOCK_ESCALATION = AUTO -- or TABLE or DISABLE ) GO
Chciałbym dodać kilka uwag na temat eskalacji blokady. Jeśli masz tabelę podzieloną na partycje, możemy ustawić eskalację na poziom partycji.
W tym kroku wykonamy zapytanie, które utworzy blokadę w tabeli AdventureWorks HumanResources. Ta tabela zawiera indeksy klastrowe i nieklastrowe.
BEGIN TRAN UPDATE [HumanResources].[Department] SET Name='NewName' where DepartmentID=1
Jak widać w poniższym okienku wyników, nasza transakcja uzyskuje blokady na wyłączność w kluczu indeksu klastra PK_Department_IDID, a także uzyskuje blokady na wyłączność w kluczu indeksu nieklastrowanego AK_Nazwa_działu. Teraz możemy zadać pytanie „Dlaczego SQL Server blokuje indeks nieklastrowany?”
Nazwa kolumna jest indeksowana w nieklastrowanym indeksie AK_Department_Name i próbujemy zmienić Nazwa kolumna. W takim przypadku SQL Server musi zmienić wszystkie indeksy nieklastrowane w tej kolumnie. Poziom liścia indeksu nieklastrowanego obejmuje każdą uporządkowaną wartość KEY.
Wnioski
W tym artykule wspomnieliśmy o głównych liniach mechanizmu blokowania SQL Server i rozważyliśmy użycie sys.dm_tran_locks. Widok sys.dm_tran_locks zwraca wiele informacji o aktualnie aktywnych zasobach blokady. Jeśli korzystasz z Google, możesz znaleźć wiele przykładowych zapytań dotyczących tego widoku.
Referencje
Przewodnik po blokowaniu transakcji w SQL Server i wersjonowaniu wierszy
SQL Server, blokuje obiekt