Analizowanie i zapobieganie zakleszczeniom w usłudze Azure SQL Database i bazie danych SQL Fabric
Dotyczy:Azure SQL Database
SQL database w Fabric
W tym artykule przedstawiono sposób identyfikowania zakleszczeń (deadlocków), używania wykresów zakleszczeń i magazynu zapytań do identyfikowania zapytań w impasie oraz planowania i testowania zmian, aby zapobiec ponownemu wystąpieniu zakleszczeń. Ten artykuł dotyczy bazy danych SQL Azure SQL Database i fabric SQL Database, która udostępnia wiele funkcji usługi Azure SQL Database.
Ten artykuł koncentruje się na identyfikowaniu i analizowaniu zakleszczeń ze względu na rywalizację o blokadę. Dowiedz się więcej o innych typach zakleszczeń w zasobach, które mogą się zakleszczać.
Jak występują zakleszczenia
Każda nowa baza danych w usłudze Azure SQL Database ma domyślnie włączone ustawienie bazy danych izolacji migawkowej na poziomie odczytu zatwierdzonego (RCSI). Blokowanie między sesjami odczytu danych i sesjami zapisu danych jest zminimalizowane w ramach RCSI, który używa wersjonowania wierszy w celu zwiększenia współbieżności. Jednak blokowanie i zakleszczenia mogą nadal występować w bazach danych w usłudze Azure SQL Database, ponieważ:
Zapytania modyfikujące dane mogą blokować się nawzajem.
Zapytania mogą być uruchamiane na poziomach izolacji, które zwiększają blokowanie. Poziomy izolacji można określić za pomocą metod biblioteki klienta, wskazówek dotyczących zapytańlub USTAWIĆ POZIOM IZOLACJI TRANSAKCJI w języku Transact-SQL.
RCSI może być wyłączona, co powoduje, że baza danych używa udostępnionych blokad (S) w celu ochrony instrukcji
SELECT
uruchamianych na poziomie izolacji zatwierdzonej do odczytu. Może to zwiększyć blokowanie i zakleszczenia.
Przykład zakleszczenia
Zakleszczenie występuje, gdy dwa lub więcej zadań trwale blokuje się nawzajem, ponieważ każde z nich ma blokadę zasobu, który drugie zadanie próbuje zablokować. Zakleszczenie jest również nazywane cykliczną zależnością: w przypadku zakleszczenia obejmującego dwa zadania, transakcja A ma zależność od transakcji B, a transakcja B zamyka cykl, mając zależność od transakcji A.
Na przykład:
Sesja A rozpoczyna transakcję jawną i uruchamia instrukcję aktualizacji, która uzyskuje blokadę aktualizacji (U) w jednym wierszu w tabeli
SalesLT.Product
, który jest konwertowany na blokadę wyłączną (X).Sesja B uruchamia instrukcję aktualizacji, która modyfikuje tabelę
SalesLT.ProductDescription
. Instrukcja update łączy się z tabeląSalesLT.Product
, aby znaleźć poprawne wiersze do zaktualizowania.Sesja B uzyskuje blokadę aktualizacji (U) na 72 wierszach w
SalesLT.ProductDescription
tabeli.Sesja B wymaga udostępnionej blokady wierszy w tabeli
SalesLT.Product
, w tym wiersza zablokowanego przez sesję A. Sesja B jest zablokowana w dniuSalesLT.Product
.
Sesja A kontynuuje transakcję, a teraz uruchamia aktualizację względem
SalesLT.ProductDescription
tabeli. Sesja A jest blokowana przez sesję B w dniuSalesLT.ProductDescription
.
Wszystkie transakcje w impasie czekają na czas nieokreślony, chyba że jedna z uczestniczących transakcji zostanie wycofana, na przykład z powodu zakończenia sesji.
Monitor zakleszczeń silnika bazy danych okresowo sprawdza obecność zadań, które są w zakleszczeniu. Jeśli monitor zakleszczenia wykryje cykliczną zależność, wybiera jedno z zadań jako ofiarę i kończy transakcję z błędem 1205: Transaction (Process ID <N>) was deadlocked on lock resources with another process and is chosen as the deadlock victim. Rerun the transaction.
Przerwanie zakleszczenia w ten sposób umożliwia innym zadaniom w zakleszczeniu ukończenie swoich transakcji.
Uwaga
Dowiedz się więcej o kryteriach wybierania ofiary zakleszczenia w sekcji lista procesów zakleszczenia tego artykułu.
Aplikacja z transakcją wybraną jako ofiara zakleszczenia powinna spróbować ponownie wykonać transakcję, która zwykle kończy się po zakończeniu drugiej transakcji lub transakcji zaangażowanych w zakleszczenie.
Najlepszym rozwiązaniem jest wprowadzenie krótkiego, losowego opóźnienia przed ponowną próbą, aby uniknąć ponownego napotkania tego samego impasu. Dowiedz się więcej na temat projektowania logiki ponawiania prób dla błędów przejściowych.
Domyślny poziom izolacji w usłudze Azure SQL Database
Nowe bazy danych w usłudze Azure SQL Database domyślnie włączają migawkę zatwierdzoną do odczytu (RCSI). RCSI zmienia zachowanie poziomu izolacji zatwierdzonej do odczytu , aby wykorzystywać wersjonowanie wierszy i zapewniać spójność na poziomie instrukcji bez użycia współdzielonych blokad (S) dla instrukcji SELECT
.
Z włączoną funkcją RCSI:
- Instrukcje odczytujące dane nie blokują instrukcji modyfikujących dane.
- Instrukcje modyfikujące dane nie blokują instrukcji odczytu danych.
Poziom izolacji opartej na migawek jest również domyślnie włączony dla nowych baz danych w usłudze Azure SQL Database. Izolacja migawki to dodatkowy poziom izolacji oparty na wierszach, który zapewnia spójność danych na poziomie transakcji. Używa ona wersji wierszy do wybierania i aktualizowania wierszy. Aby użyć izolacji migawki, zapytania lub połączenia muszą jawnie ustawić poziom izolacji transakcji na SNAPSHOT
. Można to zrobić tylko wtedy, gdy dla bazy danych jest włączona izolacja migawki.
Możesz sprawdzić, czy w języku Transact-SQL jest włączona izolacja danych RCSI i/lub izolacja migawkowa. Połącz się z bazą danych w usłudze Azure SQL Database i uruchom następujące zapytanie:
SELECT name,
is_read_committed_snapshot_on,
snapshot_isolation_state_desc
FROM sys.databases
WHERE name = DB_NAME();
GO
Jeśli opcja RCSI jest włączona, kolumna is_read_committed_snapshot_on
zwraca wartość 1
. Jeśli izolacja migawki jest włączona, kolumna snapshot_isolation_state_desc
zwraca wartość ON
.
Jeśli RCSI jest wyłączona dla bazy danych w usłudze Azure SQL Database, sprawdź, dlaczego funkcja RCSI została wyłączona przed ponownym włączeniem. Kod aplikacji może oczekiwać, że zapytania odczytujące dane będą blokowane przez zapytania zapisujące dane, co powoduje nieprawidłowe wyniki z warunków wyścigu po włączeniu funkcji RCSI.
Interpretuj zdarzenia zakleszczenia
Zdarzenie blokady jest generowane po tym, jak menedżer blokad w usłudze Azure SQL Database wykryje blokadę i wybierze transakcję jako ofiarę. Innymi słowy, jeśli skonfigurujesz alerty dotyczące zakleszczeń, powiadomienie zostanie wysłane, gdy tylko zostanie rozwiązane pojedyncze zakleszczenie. Użytkownik nie musi podejmować żadnych działań w związku z tym zakleszczeniem. Aplikacje powinny być zapisywane w celu uwzględnienia logiki ponawiania prób, aby były one automatycznie kontynuowane po otrzymaniu błędu 1205: Transaction (Process ID <N>) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Warto jednak skonfigurować alerty, ponieważ zakleszczenia mogą się powtarzać. Alerty zakleszczenia umożliwiają sprawdzenie, czy w bazie danych występuje wzorzec powtarzających się zakleszczeń, w takim przypadku można podjąć działania, aby zapobiec ponownemu zakleszczeniu. Dowiedz się więcej na temat alertów w sekcji Monitorowanie i alerty dotyczące zakleszczeń w tym artykule.
Najważniejsze metody zapobiegania zakleszczeniom
Podejście minimalizujące ryzyko zapobiegania zakleszczeniom przed ponownym wystąpieniem polega zazwyczaj na dostrajaniu indeksów nieklastrowanych w celu optymalizacji zapytań związanych z zakleszczeniem.
Ryzyko jest niskie w przypadku tego podejścia, ponieważ dostrajanie indeksów nieklastrowanych nie wymaga zmian w kodzie zapytania, co zmniejsza ryzyko błędu użytkownika podczas ponownego zapisywania języka Transact-SQL, co powoduje zwrócenie użytkownikowi nieprawidłowych danych.
Skuteczne dostrajanie indeksu nieklastrowanego pomaga wyszukiwać dane w celu bardziej wydajnego odczytywania i modyfikowania. Dzięki zmniejszeniu ilości danych, do których musi uzyskać dostęp zapytanie, prawdopodobieństwo blokowania jest zmniejszane i często można zapobiec zakleszczeniom.
W niektórych przypadkach tworzenie lub dostrajanie indeksu klastrowanego może zmniejszyć blokowanie i zakleszczenia. Ponieważ indeks klastrowany jest uwzględniany we wszystkich definicjach indeksów nieklastrowanych, tworzenie lub modyfikowanie indeksu klastrowanego może być operacją wymagającą dużej liczby operacji we/wy i czasochłonną na większych tabelach z istniejącymi indeksami nieklastrowanymi. Dowiedz się więcej na temat wytycznych dotyczących projektowania indeksu klastrowanego.
Gdy dostrajanie indeksu nie powiedzie się w zapobieganiu zakleszczeniom, dostępne są inne metody:
Jeśli zakleszczenie występuje tylko wtedy, gdy określony plan zostanie wybrany dla jednego z zapytań zaangażowanych w zakleszczenie, wymuszanie planu zapytania z Magazynem Zapytań może uniemożliwić ponownego wystąpienia zakleszczeń.
Przepisanie kodu Transact-SQL dla jednej lub kilku transakcji, które uczestniczą w zakleszczeniu, może również pomóc w zapobieganiu takim sytuacjom. Podzielenie jawnych transakcji na mniejsze transakcje wymaga starannego kodowania i testowania, aby zapewnić ważność danych podczas współbieżnych modyfikacji.
Dowiedz się więcej o każdym z tych podejść w sekcji Zapobieganie ponownemu pojawieniu się zakleszczenia w tym artykule.
Monitorowanie i wysyłanie alertów o zakleszczeniach
W tym artykule użyjemy przykładowej bazy danych AdventureWorksLT
do skonfigurowania alertów dotyczących zakleszczeń, spowodowania przykładowego zakleszczenia, przeanalizowania wykresu zakleszczenia dla przykładowego zakleszczenia i przetestowania zmian, aby zapobiec ponownemu zakleszczeniu.
W tym artykule używamy klienta programu SQL Server Management Studio (SSMS), ponieważ zawiera on możliwość wyświetlania wykresów zakleszczeń w trybie interaktywnego widoku wizualnego. Możesz używać innych klientów, takich jak Azure Data Studio, aby śledzić przykłady, ale być może będziesz mógł wyświetlać wykresy zakleszczenia tylko w formacie XML.
Tworzenie bazy danych AdventureWorksLT
Aby postępować zgodnie z przykładami, utwórz nową bazę danych w usłudze Azure SQL Database i wybierz pozycję Przykładowe dane jako źródło danych.
Aby uzyskać szczegółowe instrukcje dotyczące tworzenia przy użyciu AdventureWorksLT
portalu Azure, Azure CLI lub PowerShell, wybierz wybrane podejście w przewodniku 'Szybki start: tworzenie pojedynczej bazy danych Azure SQL Database'.
Skonfiguruj alerty zakleszczeń w portalu Azure
Aby skonfigurować alerty dotyczące sytuacji zakleszczenia, wykonaj kroki opisane w artykule Tworzenie alertów dla usług Azure SQL Database i Azure Synapse Analytics przy użyciu portalu Azure.
Wybierz pozycję Zakleszczenia jako nazwę sygnału alertu. Skonfiguruj grupę akcji, aby powiadomić Cię przy użyciu wybranej metody, takiej jak typ akcji Email/SMS/Push/Voice.
Zbieranie wykresów zakleszczenia w usłudze Azure SQL Database przy użyciu zdarzeń rozszerzonych
Wykresy zablokowań są bogatym źródłem informacji dotyczących procesów i blokad związanych z impasem. Aby zebrać wykresy zakleszczenia ze zdarzeniami rozszerzonymi (XEvents) w usłudze Azure SQL Database, przechwyć zdarzenie sqlserver.database_xml_deadlock_report
.
Wykresy zakleszczenia można zbierać przy użyciu XEvents, wybierając jako cel bufor pierścieniowy lub plik zdarzeń. Zagadnienia dotyczące wybierania odpowiedniego typu docelowego zostały podsumowane w poniższej tabeli:
Metoda | Świadczenia | Kwestie wymagające rozważenia | Scenariusze użycia |
---|---|---|---|
Element docelowy buforu pierścieniowego | — Prosta konfiguracja tylko przy użyciu Transact-SQL. | — Dane zdarzenia są usuwane, gdy sesja XEvents zostanie zatrzymana z jakiegokolwiek powodu, na przykład w przypadku przełączania bazy danych w tryb offline lub awaryjnego przełączenia bazy danych. — Zasoby bazy danych są używane do obsługi danych w buforze pierścieniowym i wykonywania zapytań dotyczących danych sesji. |
— Zbieranie przykładowych danych śledzenia na potrzeby testowania i uczenia. — Utwórz dla potrzeb krótkoterminowych, jeśli nie można natychmiast skonfigurować sesji przy użyciu obiektu docelowego pliku zdarzeń. — Użyj jako platforma początkowa dla danych śledzenia, gdy masz skonfigurowany zautomatyzowany proces zapisywania danych śledzenia w tabeli. |
Miejsce docelowe pliku zdarzenia | — Przechowuje dane zdarzeń w obiekcie blob w usłudze Azure Storage, dzięki czemu dane są dostępne nawet po zatrzymaniu sesji. — Pliki zdarzeń można pobrać z witryny Azure Portal lub Eksploratora usługi Azure Storage i analizować lokalnie, co nie wymaga używania zasobów bazy danych do wykonywania zapytań dotyczących danych sesji. |
— Konfiguracja jest bardziej złożona i wymaga konfiguracji kontenera usługi Azure Storage i poświadczeń o zakresie bazy danych. | — Do ogólnego użytku, gdy chcesz, aby dane zdarzeń były utrwalane nawet po zakończeniu sesji zdarzeń. — Chcesz uruchomić ślad, który generuje większe ilości danych zdarzeń niż chcesz zachować w pamięci. |
Wybierz typ docelowy, którego chcesz użyć:
Cel buforu pierścieniowego jest wygodny i łatwy do skonfigurowania, ale ma ograniczoną pojemność, co może spowodować utratę starszych zdarzeń. Bufor pierścieniowy nie zapisuje zdarzeń w pamięci, a docelowy bufor pierścieniowy jest czyszczony po zatrzymaniu sesji XEvents. Oznacza to, że wszystkie zebrane XEvents nie są dostępne, gdy aparat bazy danych zostanie ponownie uruchomiony z dowolnego powodu, na przykład w przypadku przełączenia awaryjnego. Cel buforu pierścienia najlepiej nadaje się do nauki i krótkoterminowych potrzeb, jeśli nie masz możliwości natychmiastowego skonfigurowania sesji XEvents na pliku docelowym zdarzeń.
Ten kod przykładowy tworzy sesję XEvents, która rejestruje wykresy blokad w pamięci przy użyciu celu bufora pierścieniowego. Maksymalna dozwolona pamięć dla docelowego buforu pierścieniowego wynosi 4 MB, a sesja jest uruchamiana automatycznie, gdy baza danych jest w trybie online, na przykład po przejściu w tryb failover.
Aby utworzyć i uruchomić sesję XEvents dla zdarzenia sqlserver.database_xml_deadlock_report
, które zapisuje w buforze pierścieniowym celu, połącz się z bazą danych i uruchom następujący kod Transact-SQL:
CREATE EVENT SESSION [deadlocks] ON DATABASE
ADD EVENT sqlserver.database_xml_deadlock_report
ADD TARGET package0.ring_buffer
WITH
(
STARTUP_STATE = ON,
MAX_MEMORY = 4 MB
);
GO
ALTER EVENT SESSION [deadlocks] ON DATABASE
STATE = START;
GO
Przyczyna zakleszczenia w AdventureWorksLT
Uwaga
Ten przykład działa w bazie danych AdventureWorksLT
z domyślnym schematem i danymi po włączeniu funkcji RCSI. Aby uzyskać instrukcje dotyczące tworzenia bazy danych, zobacz Tworzenie bazy danych AdventureWorksLT.
Aby spowodować zakleszczenie, należy połączyć dwie sesje z bazą danych AdventureWorksLT
. Te sesje określamy jako Sesja A i Sesja B.
W sesji A wykonaj następujące polecenie Transact-SQL. Ten kod rozpoczyna jawną transakcję i uruchamia pojedynczą instrukcję, która aktualizuje tabelęSalesLT.Product
. Aby to zrobić, transakcja uzyskuje blokadę aktualizacyjną (U) na jednym wierszu w tabeli SalesLT.Product
, która jest następnie przekształcana w blokadę wyłączną (X). Pozostawimy otwartą transakcję.
BEGIN TRANSACTION;
UPDATE SalesLT.Product
SET SellEndDate = SellEndDate + 1
WHERE Color = 'Red';
Teraz w sesji B uruchom następujący kod Transact-SQL. Ten kod nie rozpoczyna jawnie transakcji. Zamiast tego działa w trybie automatycznego zatwierdzania transakcji. Ta instrukcja aktualizuje tabelę SalesLT.ProductDescription
. Aktualizacja ustawia blokadę aktualizacyjną (U) na 72 wierszach w tabeli SalesLT.ProductDescription
. Zapytanie łączy się z innymi tabelami, w tym z tabelą SalesLT.Product
.
UPDATE SalesLT.ProductDescription
SET Description = Description
FROM SalesLT.ProductDescription AS pd
INNER JOIN SalesLT.ProductModelProductDescription AS pmpd
ON pd.ProductDescriptionID = pmpd.ProductDescriptionID
INNER JOIN SalesLT.ProductModel AS pm
ON pmpd.ProductModelID = pm.ProductModelID
INNER JOIN SalesLT.Product AS p
ON pm.ProductModelID = p.ProductModelID
WHERE p.Color = 'Silver';
Aby ukończyć tę aktualizację, sesja B wymaga współużytkowanej blokady (S) na wiersze w tabeli SalesLT.Product
, w tym wiersza zablokowanego przez sesję A. sesja B jest zablokowana na SalesLT.Product
.
Wróć do sesji A. Uruchom następującą instrukcję języka Transact-SQL. Spowoduje to uruchomienie drugiej instrukcji UPDATE
w ramach otwartej transakcji.
UPDATE SalesLT.ProductDescription
SET Description = Description
FROM SalesLT.ProductDescription AS pd
INNER JOIN SalesLT.ProductModelProductDescription AS pmpd
ON pd.ProductDescriptionID = pmpd.ProductDescriptionID
INNER JOIN SalesLT.ProductModel AS pm
ON pmpd.ProductModelID = pm.ProductModelID
INNER JOIN SalesLT.Product AS p
ON pm.ProductModelID = p.ProductModelID
WHERE p.Color = 'Red';
Drugie polecenie aktualizacji w sesji A jest blokowane przez sesję B na SalesLT.ProductDescription
.
Sesja A i Sesja B wzajemnie się blokują. Żadna transakcja nie może kontynuować, ponieważ każda z nich potrzebuje zasobu zablokowanego przez drugą.
Po kilku sekundach monitor zakleszczenia identyfikuje, że transakcje w sesji A oraz sesji B blokują się nawzajem i że żadna z nich nie może poczynić postępów. Powinno wystąpić zakleszczenie, a sesja A zostanie wybrana jako jego ofiara. Komunikat o błędzie jest wyświetlany w sesji A z tekstem podobnym do następującego:
Msg 1205, Level 13, State 51, Line 7
Transaction (Process ID 91) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Sesja B kończy się pomyślnie.
Jeśli skonfigurujesz alerty zakleszczenia w portalu Azure, powinieneś otrzymać powiadomienie wkrótce po wystąpieniu zakleszczenia.
Wyświetl wykresy zakleszczenia z sesji XEvents
Jeśli skonfigurujesz sesję XEvents, aby zbierać zakleszczenia i zakleszczenie wystąpi po rozpoczęciu sesji, możesz wyświetlić interaktywne graficzne przedstawienie grafu zakleszczenia oraz XML tego grafu.
Dostępne są różne metody uzyskiwania informacji o zakleszczeniach dla obiektów docelowych buforu pierścienia i obiektów docelowych plików zdarzeń. Wybierz element docelowy używany dla sesji XEvents:
Jeśli skonfigurujesz sesję XEvents do zapisu w buforze pierścienia, możesz wykonywać zapytania dotyczące zakleszczeń przy użyciu następującego Transact-SQL. Przed uruchomieniem zapytania zastąp wartość @tracename
nazwą sesji XEvents.
DECLARE @tracename AS sysname = N'deadlocks';
WITH ring_buffer
AS (SELECT CAST (target_data AS XML) AS rb
FROM sys.dm_xe_database_sessions AS s
INNER JOIN sys.dm_xe_database_session_targets AS t
ON CAST (t.event_session_address AS BINARY (8)) = CAST (s.address AS BINARY (8))
WHERE s.name = @tracename
AND t.target_name = N'ring_buffer'),
dx
AS (SELECT dxdr.evtdata.query('.') AS deadlock_xml_deadlock_report
FROM ring_buffer
CROSS APPLY rb.nodes('/RingBufferTarget/event[@name=''database_xml_deadlock_report'']') AS dxdr(evtdata))
SELECT d.query('/event/data[@name=''deadlock_cycle_id'']/value').value('(/value)[1]', 'int') AS [deadlock_cycle_id],
d.value('(/event/@timestamp)[1]', 'DateTime2') AS [deadlock_timestamp],
d.query('/event/data[@name=''database_name'']/value').value('(/value)[1]', 'nvarchar(256)') AS [database_name],
d.query('/event/data[@name=''xml_report'']/value/deadlock') AS deadlock_xml,
LTRIM(RTRIM(REPLACE(REPLACE(d.value('.', 'nvarchar(2000)'), CHAR(10), ' '), CHAR(13), ' '))) AS query_text
FROM dx
CROSS APPLY deadlock_xml_deadlock_report.nodes('(/event/data/value/deadlock/process-list/process/inputbuf)') AS ib(d)
ORDER BY [deadlock_timestamp] DESC;
GO
Wyświetl i zapisz graf zakleszczenia w formacie XML
Wyświetlanie wykresu zakleszczenia w XML pozwala kopiować inputbuffer
instrukcje Transact-SQL związane z zakleszczeniem. Możesz także analizować zatory w formacie tekstowym.
Jeśli użyto zapytania Transact-SQL w celu zwrócenia informacji o grafie zakleszczenia, aby wyświetlić jego kod XML, wybierz wartość w kolumnie deadlock_xml
z dowolnego wiersza. Otworzy to kod XML grafu zakleszczenia w nowym oknie w programie SSMS.
Kod XML dla tego przykładowego grafu zakleszczenia to:
<deadlock>
<victim-list>
<victimProcess id="process24756e75088" />
</victim-list>
<process-list>
<process id="process24756e75088" taskpriority="0" logused="6528" waitresource="KEY: 8:72057594045202432 (98ec012aa510)" waittime="192" ownerId="1011123" transactionname="user_transaction" lasttranstarted="2022-03-08T15:44:43.490" XDES="0x2475c980428" lockMode="U" schedulerid="3" kpid="30192" status="suspended" spid="89" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-03-08T15:44:49.250" lastbatchcompleted="2022-03-08T15:44:49.210" lastattention="1900-01-01T00:00:00.210" clientapp="Microsoft SQL Server Management Studio - Query" hostname="LAPTOP-CHRISQ" hostpid="16716" loginname="chrisqpublic" isolationlevel="read committed (2)" xactid="1011123" currentdb="8" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671096864" clientoption2="128056">
<executionStack>
<frame procname="unknown" queryhash="0xef52b103e8b9b8ca" queryplanhash="0x02b0f58d7730f798" line="1" stmtstart="2" stmtend="792" sqlhandle="0x02000000c58b8f1e24e8f104a930776e21254b1771f92a520000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
UPDATE SalesLT.ProductDescription SET Description = Description
FROM SalesLT.ProductDescription as pd
JOIN SalesLT.ProductModelProductDescription as pmpd on
pd.ProductDescriptionID = pmpd.ProductDescriptionID
JOIN SalesLT.ProductModel as pm on
pmpd.ProductModelID = pm.ProductModelID
JOIN SalesLT.Product as p on
pm.ProductModelID=p.ProductModelID
WHERE p.Color = 'Red' </inputbuf>
</process>
<process id="process2476d07d088" taskpriority="0" logused="11360" waitresource="KEY: 8:72057594045267968 (39e18040972e)" waittime="2641" ownerId="1013536" transactionname="UPDATE" lasttranstarted="2022-03-08T15:44:46.807" XDES="0x2475ca80428" lockMode="S" schedulerid="2" kpid="94040" status="suspended" spid="95" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-03-08T15:44:46.807" lastbatchcompleted="2022-03-08T15:44:46.760" lastattention="1900-01-01T00:00:00.760" clientapp="Microsoft SQL Server Management Studio - Query" hostname="LAPTOP-CHRISQ" hostpid="16716" loginname="chrisqpublic" isolationlevel="read committed (2)" xactid="1013536" currentdb="8" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="unknown" queryhash="0xef52b103e8b9b8ca" queryplanhash="0x02b0f58d7730f798" line="1" stmtstart="2" stmtend="798" sqlhandle="0x020000002c85bb06327c0852c0be840fc1e30efce2b7c8090000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
UPDATE SalesLT.ProductDescription SET Description = Description
FROM SalesLT.ProductDescription as pd
JOIN SalesLT.ProductModelProductDescription as pmpd on
pd.ProductDescriptionID = pmpd.ProductDescriptionID
JOIN SalesLT.ProductModel as pm on
pmpd.ProductModelID = pm.ProductModelID
JOIN SalesLT.Product as p on
pm.ProductModelID=p.ProductModelID
WHERE p.Color = 'Silver'; </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594045202432" dbid="8" objectname="9e011567-2446-4213-9617-bad2624ccc30.SalesLT.ProductDescription" indexname="PK_ProductDescription_ProductDescriptionID" id="lock2474df12080" mode="U" associatedObjectId="72057594045202432">
<owner-list>
<owner id="process2476d07d088" mode="U" />
</owner-list>
<waiter-list>
<waiter id="process24756e75088" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594045267968" dbid="8" objectname="9e011567-2446-4213-9617-bad2624ccc30.SalesLT.Product" indexname="PK_Product_ProductID" id="lock2474b588580" mode="X" associatedObjectId="72057594045267968">
<owner-list>
<owner id="process24756e75088" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process2476d07d088" mode="S" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
Aby zapisać graf zakleszczenia jako plik XML:
- Wybierz pozycję Plik i Zapisz jako....
- Pozostaw wartość Zapisz jako typ jako domyślną wartość Pliki XML (*.xml)
- Ustaw nazwę pliku na wybraną nazwę.
- Wybierz pozycję Zapisz.
Zapisz graf zakleszczenia jako plik XDL, który może być wyświetlany interaktywnie w programie SSMS.
Wyświetlenie interaktywnej reprezentacji grafu zakleszczenia może być przydatne, aby uzyskać szybki przegląd procesów i zasobów związanych z zakleszczeniem oraz szybko zidentyfikować ofiarę zakleszczenia.
Aby zapisać wykres zakleszczenia jako plik, który może być wyświetlany graficznie przez program SSMS:
Wybierz wartość w kolumnie
deadlock_xml
z dowolnego wiersza, aby otworzyć kod XML grafu zakleszczenia w nowym oknie w programie SSMS.Wybierz pozycję Plik i Zapisz jako....
Ustaw pozycję Zapisz jako typ na Wszystkie pliki.
Ustaw nazwę pliku na wybraną nazwę, a rozszerzenie ma wartość
.xdl
.Wybierz pozycję Zapisz.
Zamknij plik, wybierając ikonę X na karcie w górnej części okna lub wybierając pozycję Plik, a następnie zamknij.
Otwórz ponownie plik w programie SSMS, wybierając Plik, a następnie Otwórz, a potem Plik. Wybierz zapisany plik z
.xdl
rozszerzeniem .Teraz wykres zakleszczenia jest wyświetlany w SSMS jako wizualna reprezentacja procesów i zasobów zaangażowanych w zakleszczenie.
Analizowanie zablokowania dla usługi Azure SQL Database
Wykres zakleszczenia zwykle ma trzy węzły:
Lista ofiar. Identyfikator procesu ofiary zakleszczenia.
Lista procesów. Informacje o wszystkich procesach związanych z zablokowaniem. Wykresy zakleszczeń używają terminu "proces" do określania sesji, w której uruchomiona jest transakcja.
Lista zasobów. Informacje na temat zasobów zaangażowanych w zakleszczenie.
Podczas analizowania zakleszczenia warto krok po kroku przejrzeć te węzły.
Lista ofiar deadlocku
Lista ofiar zakleszczenia pokazuje proces, który został wybrany jako ofiara zakleszczenia. W wizualnej reprezentacji grafu zakleszczenia procesy są reprezentowane przez owale. Proces ofiary zakleszczenia ma "X" narysowane na owalu.
W widoku XML grafu zakleszczeniavictim-list
węzeł podaje identyfikator procesu, który był ofiarą zakleszczenia.
W naszym przykładzie zakleszczenia identyfikatorem procesu ofiary jest process24756e75088
. Możemy użyć tego identyfikatora podczas badania węzłów listy procesów i listy zasobów, aby dowiedzieć się więcej o procesie ofiary i zasobach, które zablokowała lub zażądała blokady.
Lista procesów zakleszczenia
Lista procesów zakleszczenia jest bogatym źródłem informacji o transakcjach biorących udział w zakleszczeniu.
Graficzne przedstawienie wykresu zakleszczenia przedstawia tylko podzbiór informacji zawartych w pliku XML wykresu zakleszczenia. Owale na wykresie zakleszczeń reprezentują proces, pokazując informacje, w tym:
Identyfikator sesji, znany również jako SPID.
Priorytet zakleszczenia sesji. Jeśli dwie sesje mają różne priorytety zakleszczenia, ta z niższym priorytetem zostaje wybrana jako ofiara zakleszczenia. W tym przykładzie obie sesje mają ten sam priorytet zakleszczenia.
Ilość dziennika transakcji używanego przez sesję w bajtach. Jeśli obie sesje mają taki sam priorytet zakleszczenia, monitor zakleszczenia wybiera sesję, którą taniej jest wycofać jako ofiarę zakleszczenia. Koszt jest określany przez porównanie liczby bajtów dziennika zapisanych w tym punkcie w każdej transakcji.
W naszym przykładzie zakleszczenia, węzeł
session_id
89 użył mniejszej ilości dziennika transakcji i został wybrany jako ofiara zakleszczenia.
Ponadto można wyświetlić bufor wejściowy dla ostatniej instrukcji uruchomionej w każdej sesji przed zakleszczeniem, umieszczając wskaźnik myszy nad każdym procesem. Bufor wejściowy jest wyświetlany w etykietce narzędzia.
Dodatkowe informacje są dostępne dla procesów w grafu zakleszczenia widoku XML, w tym:
Identyfikowanie informacji dotyczących sesji, takich jak nazwa klienta, nazwa hosta i nazwa logowania.
Skrót planu zapytania dla ostatniego polecenia uruchomionego przez każdą sesję przed wystąpieniem zakleszczenia. Skrót planu zapytania jest przydatny do pobierania dodatkowych informacji o zapytaniu z magazynu zapytań.
W naszym przykładzie zakleszczenia:
Widzimy, że obie sesje zostały uruchomione przy użyciu klienta SSMS z logowaniem
chrisqpublic
.Skrót planu zapytania SQL ostatniego zapytania uruchomionego przed zakleszczeniem przez naszą ofiarę zakleszczenia to
0x02b0f58d7730f798
. Tekst tej instrukcji można zobaczyć w buforze wejściowym.Skrót planu zapytania z ostatniego polecenia uruchomionego przez inną sesję w naszym zakleszczeniu to także
0x02b0f58d7730f798
. Tekst tej instrukcji można zobaczyć w buforze wejściowym. W takim przypadku oba zapytania mają ten sam skrót planu zapytania, ponieważ zapytania są identyczne, z wyjątkiem wartości literału używanej jako predykat równości.
W dalszej części tego artykułu użyjemy tych wartości, aby znaleźć dodatkowe informacje w Query Store.
Ograniczenia buforu wejściowego w liście procesów zakleszczonych
Należy wziąć pod uwagę kilka ograniczeń dotyczących informacji o buforze wejściowym w liście procesu zakleszczenia.
Tekst zapytania może zostać obcięty w buforze wejściowym. Bufor wejściowy jest ograniczony do pierwszych 4000 znaków wykonywanej instrukcji.
Ponadto niektóre oświadczenia związane z impasem mogą nie być uwzględnione w grafie zakleszczenia. W naszym przykładzie sesja A uruchomiła dwie instrukcje aktualizacji w ramach jednej transakcji. Tylko druga instrukcja aktualizacji, aktualizacja, która spowodowała zakleszczenie, jest uwzględniona w grafie zakleszczenia. Pierwsza instrukcja aktualizacji uruchamiana przez Sesję A odegrała rolę w impasie, blokując Sesję B. Bufor wejściowy, query_hash
, i powiązane informacje dotyczące pierwszej instrukcji uruchamianej przez Sesję A nie są uwzględniane w grafie zakleszczenia.
Aby zidentyfikować pełne polecenie Transact-SQL w transakcji wieloinstrukcyjnej zaangażowanej w zakleszczenie, należy znaleźć odpowiednie informacje w procedurze składowanej lub w kodzie aplikacji, które uruchomiły to zapytanie, lub przeprowadzić śledzenie za pomocą zdarzeń rozszerzonych, aby rejestrować pełne instrukcje uruchamiane przez sesje uczestniczące w zakleszczeniu w momencie jego występowania. Jeśli instrukcja związana z zakleszczeniem została obcięta i w buforze wejściowym znajduje się tylko częściowy kod Transact-SQL, można znaleźć kod Transact-SQL dla tej instrukcji w magazynie zapytań wraz z planem wykonania.
Lista zasobów zakleszczenia
Lista zasobów zakleszczenia pokazuje, które zasoby blokady są posiadane i oczekiwane przez procesy w zakleszczeniu.
W wizualnej reprezentacji zakleszczenia zasoby są przedstawiane jako prostokąty.
Uwaga
Nazwy baz danych są reprezentowane jako identyfikatory GUID (uniqueidentifier) w grafach blokad dla baz danych w Azure SQL Database. To jest physical_database_name
dla bazy danych wymienionej w dynamicznych widokach zarządzania sys.databases i sys.dm_user_db_resource_governance.
W tym przykładzie 'zakleszczenie':
Ofiara zakleszczenia, którą nazwaliśmy Sesja A:
Jest właścicielem blokady wyłącznej (X) na kluczu w indeksie
PK_Product_ProductID
wSalesLT.Product
tabeli.Żąda blokady aktualizacji (U) na kluczu w indeksie
PK_ProductDescription_ProductDescriptionID
na tabeliSalesLT.ProductDescription
.
Drugi proces, który nazywamy sesją B:
Jest właścicielem blokady aktualizacji (U) na kluczu w indeksie
PK_ProductDescription_ProductDescriptionID
w tabeliSalesLT.ProductDescription
.Żąda blokady udostępnionej (S) na kluczu w indeksie
PK_ProductDescription_ProductDescriptionID
wSalesLT.ProductDescription
tabeli.
Możemy zobaczyć te same informacje w graficznym przedstawieniu zakleszczenia w XML w węźle lista-zasobów.
Znajdowanie planów wykonywania zapytań w magazynie zapytań
Często przydatne jest sprawdzenie planów wykonania zapytań uczestniczących w zakleszczeniu. Te plany wykonywania można często znaleźć w repozytorium zapytań, używając skrótu planu zapytania z widoku XML listy procesów w grafie zakleszczenia.
To zapytanie Transact-SQL wyszukuje plany zapytań odpowiadające skrótowi planu zapytania, który znaleźliśmy dla naszego przykładowego zakleszczenia. Połącz się z bazą danych użytkownika w usłudze Azure SQL Database, aby uruchomić zapytanie.
DECLARE @query_plan_hash AS BINARY (8) = 0x02b0f58d7730f798;
SELECT qrsi.end_time AS interval_end_time,
qs.query_id,
qp.plan_id,
qt.query_sql_text,
TRY_CAST (qp.query_plan AS XML) AS query_plan,
qrs.count_executions
FROM sys.query_store_query AS qs
INNER JOIN sys.query_store_query_text AS qt
ON qs.query_text_id = qt.query_text_id
INNER JOIN sys.query_store_plan AS qp
ON qs.query_id = qp.query_id
INNER JOIN sys.query_store_runtime_stats AS qrs
ON qp.plan_id = qrs.plan_id
INNER JOIN sys.query_store_runtime_stats_interval AS qrsi
ON qrs.runtime_stats_interval_id = qrsi.runtime_stats_interval_id
WHERE query_plan_hash = @query_plan_hash
ORDER BY interval_end_time, query_id;
GO
W zależności od ustawień magazynu zapytań CLEANUP_POLICY lubustawień QUERY_CAPTURE_MODE magazynu zapytań może nie być możliwe uzyskanie planu wykonywania zapytań z magazynu zapytań. W takim przypadku często można uzyskać potrzebne informacje , wyświetlając szacowany plan wykonania zapytania.
Poszukaj wzorców, które zwiększają blokowanie
Podczas badania planów wykonywania zapytań związanych z zakleszczeniami, poszukaj wzorców, które mogą przyczynić się do blokowania i zakleszczeń.
Skanowanie tabeli lub indeksu. Gdy zapytania modyfikujące dane są uruchamiane w trybie RCSI, wybór wierszy do aktualizacji jest przeprowadzany przy użyciu skanowania blokującego, podczas którego blokada aktualizacji (U) jest nakładana na wiersz danych w miarę odczytywania wartości danych. Jeśli wiersz danych nie spełnia kryteriów aktualizacji, blokada aktualizacji zostanie zwolniona, a następny wiersz zostanie zablokowany i zeskanowany.
Dostrajanie indeksów w celu zwiększenia wydajności zapytań modyfikujących dane pomaga efektywniej znajdować wiersze, co zmniejsza liczbę wystawionych blokad aktualizacji. Zmniejsza to prawdopodobieństwo blokowania i zakleszczenia.
Indeksowane widoki odwołujące się do więcej niż jednej tabeli. Podczas modyfikowania tabeli, do której odwołuje się widok indeksowany, aparat bazy danych musi również obsługiwać indeksowany widok. Wymaga to usunięcia większej liczby blokad i może prowadzić do częstszego blokowania i zakleszczeń. Widoki indeksowane mogą również spowodować, że operacje aktualizacji są wykonywane wewnętrznie w ramach poziomu izolacji zatwierdzonej do odczytu.
Modyfikacje kolumn referencyjnych w ograniczeniach klucza obcego. Podczas modyfikowania kolumn w tabeli, do której odwołuje się ograniczenie
FOREIGN KEY
, aparat bazy danych musi szukać powiązanych wierszy w tabeli odwołującej się. Nie można używać wersji wierszy dla tych operacji odczytu. W przypadkach, gdy włączono aktualizacje lub usuwanie kaskadowe, poziom izolacji może być podniesiony do serializowalnego na czas trwania instrukcji, aby chronić przed wstawkami fantomowymi.Wskazówki dotyczące blokady. Poszukaj wskazówek tabeli, które określają poziomy izolacji wymagające większej liczby blokad. Te wskazówki obejmują
HOLDLOCK
(co jest równoważne serializacji),SERIALIZABLE
,READCOMMITTEDLOCK
(co wyłącza RCSI) iREPEATABLEREAD
. Ponadto wskazówki, takie jakPAGLOCK
,TABLOCK
,UPDLOCK
iXLOCK
mogą zwiększyć ryzyko blokowania i zakleszczenia.Jeśli te wskazówki są wdrożone, zbadaj, dlaczego je zastosowano. Te wskazówki mogą zapobiec warunkom wyścigu i zapewnić ważność danych. W razie potrzeby można pozostawić te wskazówki i zapobiec przyszłym zakleszczeniom, stosując alternatywną metodę w sekcji Zapobieganie ponownemu wystąpieniu zakleszczenia tego artykułu.
Podczas badania pełnego kodu transakcji w planie wykonywania lub w kodzie zapytania aplikacji poszukaj dodatkowych problematycznych wzorców:
Interakcja użytkownika w transakcjach. Interakcja użytkownika wewnątrz jawnej transakcji obejmującej wiele instrukcji znacznie zwiększa czas trwania transakcji. To sprawia, że jest bardziej prawdopodobne, że te transakcje będą się nakładać, co prowadzi do blokad oraz zakleszczeń.
Podobnie, trzymanie otwartej transakcji i wykonywanie zapytań do niepowiązanej bazy danych lub systemu w trakcie trwania transakcji znacznie zwiększa prawdopodobieństwo blokowania i zakleszczeń.
Transakcje uzyskujące dostęp do obiektów w różnej kolejności. Zakleszczenia są mniej prawdopodobne, gdy równoczesne wieloetapowe transakcje przestrzegają tych samych wzorców i uzyskują dostęp do obiektów w tej samej kolejności.
Zapobieganie ponownemu wystąpieniu zakleszczenia
Dostępnych jest wiele technik, które zapobiegają ponownemu występowaniu zakleszczeń, takich jak dostrajanie indeksów, wymuszanie planów za pomocą Query Store i modyfikowanie zapytań Transact-SQL.
Przejrzyj klastrowany indeks tabeli. Większość tabel korzysta z indeksów klastrowanych, ale często tabele są implementowane jako stosy przez pomyłkę.
Jednym ze sposobów sprawdzenia indeksu klastrowanego jest użycie procedury składowanej systemu sp_helpindex . Na przykład możemy wyświetlić podsumowanie indeksów w
SalesLT.Product
tabeli, wykonując następującą instrukcję:EXECUTE sp_helpindex 'SalesLT.Product'; GO
Przejrzyj kolumnę
index_description
. Tabela może zawierać tylko jeden indeks klastrowany. Jeśli indeks klastrowany został zaimplementowany dla tabeli,index_description
zawiera słowoclustered
.Jeśli nie ma indeksu klastrowanego, tabela jest stertą. W takim przypadku sprawdź, czy tabela została celowo utworzona w formie sterty, aby rozwiązać określony problem z wydajnością. Rozważ zaimplementowanie indeksu klastrowanego na podstawie wytycznych dotyczących projektowania indeksu klastrowanego.
W niektórych przypadkach tworzenie lub dostrajanie indeksu klastrowanego może zmniejszyć lub wyeliminować blokowanie w impasach. W innych przypadkach możesz stosować dodatkową technikę, taką jak inne na tej liście.
utwórz lub zmodyfikuj indeksy nieklastrowane. Dostrajanie indeksów nieklastrowanych może pomóc Twoim zapytaniom modyfikacji szybciej znajdować dane do aktualizacji, co zmniejsza liczbę wymaganych blokad aktualizacji.
W naszym przykładowym zakleszczeniu plan wykonywania zapytania znaleziony w Query Store zawiera przeszukiwanie indeksu klastrowanego na indeksie
PK_Product_ProductID
. Wykres zakleszczenia wskazuje, że oczekiwanie na blokadę współdzieloną (S) na tym indeksie jest składnikiem zakleszczenia.To skanowanie indeksu jest wykonywane, ponieważ nasze zapytanie aktualizacji musi zmodyfikować indeksowany widok o nazwie
vProductAndDescription
. Jak wspomniano w sekcji Szukaj wzorców zwiększających blokowanie tego artykułu, indeksowane widoki odwołujące się do wielu tabel mogą zwiększyć blokowanie i prawdopodobieństwo zakleszczenia.Jeśli utworzymy następujący indeks nieklastrowany w
AdventureWorksLT
bazie danych, który "obejmuje" kolumny zSalesLT.Product
przywoływanego przez indeksowany widok, pomoże to zapytaniu znaleźć wiersze znacznie wydajniej:CREATE INDEX IX_Product_ProductID_Name_ProductModelID ON SalesLT.Product(ProductID, Name, ProductModelID); GO
Po utworzeniu tego indeksu zakleszczenie już się nie powtarza.
Gdy zakleszczenia obejmują modyfikacje kolumn odwołujących się do ograniczeń klucza obcego, upewnij się, że indeksy w tabeli referencyjnej
FOREIGN KEY
umożliwiają efektywne znajdowanie powiązanych wierszy.Chociaż indeksy mogą znacznie poprawić wydajność zapytań w niektórych przypadkach, indeksy również mają koszty związane z obciążeniem i zarządzaniem. Zapoznaj się z ogólnymi wytycznymi dotyczącymi projektowania indeksów, aby ułatwić ocenę korzyści z indeksów przed utworzeniem indeksów, szczególnie szerokich indeksów i indeksów w dużych tabelach.
Oceń wartość indeksowanych widoków. Inną opcją zapobiegania ponownemu wystąpieniu naszego przykładowego zakleszczenia jest porzucenie indeksowanego widoku. Jeśli ten widok indeksowany nie jest używany, zmniejsza to nakład pracy związany z utrzymywaniem indeksowanego widoku w czasie.
Użyj izolacji migawki. W niektórych przypadkach ustawienie poziomu izolacji transakcji na migawkę dla jednej lub więcej transakcji biorących udział w zakleszczeniu może zapobiec blokowaniu i ponownemu wystąpieniu zakleszczeń.
Ta technika najprawdopodobniej powiedzie się w przypadku użycia w instrukcjach
SELECT
, gdy w bazie danych migawka potwierdzonego odczytu jest wyłączona. Gdy migawka zatwierdzona do odczytu jest wyłączona,SELECT
zapytania przy użyciu poziomu izolacji zatwierdzonej do odczytu wymagają blokad udostępnionych (S). Użycie izolacji migawki w tych transakcjach eliminuje potrzebę stosowania wspólnych blokad, co może zapobiegać blokowaniu i zakleszczeniom.W bazach danych, w których włączono izolację zatwierdzonych migawek do odczytu, zapytania
SELECT
nie wymagają blokad współdzielonych (S), dlatego zakleszczenia mogą częściej występować między transakcjami, które modyfikują dane. W przypadkach, gdy zakleszczenia występują między wieloma transakcjami modyfikującymi dane, izolacja migawki może spowodować konflikt aktualizacji zamiast zakleszczenia. Podobnie wymaga to, aby jedna z transakcji ponownie wykonała operację.Wymuś plan przy użyciu Query Store. Może się okazać, że jedno z zapytań w impasie ma wiele planów wykonywania, a impas występuje tylko wtedy, gdy zostanie użyty określony plan. Możesz zapobiec ponownemu zakleszczaniu, wymuszając plan w Query Store.
Zmodyfikuj język Transact-SQL. Aby uniknąć ponownego zakleszczenia, może być konieczne zmodyfikowanie kodu Transact-SQL. Należy starannie zmodyfikować język Transact-SQL, a zmiany powinny być rygorystycznie testowane, aby upewnić się, że dane są poprawne podczas równoczesnego uruchamiania modyfikacji. Podczas ponownego pisania języka Transact-SQL należy wziąć pod uwagę następujące kwestie:
Porządkowanie instrukcji w transakcjach w taki sposób, aby uzyskiwały dostęp do obiektów w tej samej kolejności.
Podział transakcji na mniejsze transakcje, gdy jest to możliwe.
W razie potrzeby użyj wskazówek dotyczących zapytań, aby zoptymalizować wydajność. Wskazówki można stosować bez zmieniania kodu aplikacji przy użyciu Query Store.
Znajdź więcej sposobów zminimalizowania zakleszczeń w przewodniku dotyczącym zakleszczeń.
Uwaga
W niektórych przypadkach można dostosować priorytet zablokowania jednej lub więcej sesji biorących udział w zablokowaniu, jeśli ważne jest, aby jedna z sesji zakończyła się pomyślnie bez ponownego próbowania, lub gdy jedno z zapytań zaangażowanych w zablokowanie nie jest krytyczne i powinno być zawsze wybierane jako ofiara. To nie zapobiega ponownym zakleszczeniom, jednak może zmniejszyć wpływ przyszłych zakleszczeń.
Usuwanie sesji XEvents
Możesz pozostawić działającą na krytycznych bazach danych sesję XEvents, która zbiera informacje o zakleszczeniach, przez długi czas. Jeśli używasz docelowego pliku zdarzeń, może to spowodować powstanie dużych plików, jeśli wystąpi wiele zakleszczeń. Możesz usuwać pliki Blob z usługi Azure Storage podczas aktywnego śledzenia, z wyjątkiem pliku, do którego aktualnie trwa zapis.
Jeśli chcesz usunąć sesję XEvents, polecenie Transact-SQL do usunięcia sesji jest takie samo, niezależnie od wybranego typu docelowego.
Aby usunąć sesję XEvents, uruchom następujące polecenie Języka Transact-SQL. Przed uruchomieniem kodu zastąp nazwę sesji odpowiednią wartością.
ALTER EVENT SESSION [deadlocks] ON DATABASE
STATE = STOP;
GO
DROP EVENT SESSION [deadlocks] ON DATABASE;
GO
Korzystanie z Eksploratora usługi Azure Storage
Eksplorator usługi Azure Storage to autonomiczna aplikacja, która upraszcza pracę z obiektami docelowymi plików zdarzeń przechowywanymi w obiektach blob w usłudze Azure Storage. Użyj Eksploratora magazynu, aby:
Utwórz kontener obiektów blob do przechowywania danych sesji X-Event.
Pobierz sygnaturę dostępu współdzielonego (SAS) dla kontenera blob.
Jak wspomniano w artykule Zbieranie wykresów zakleszczenia w usłudze Azure SQL Database z użyciem zdarzeń rozszerzonych, wymagane są uprawnienia do odczytu, zapisu i do wyświetlania.
Usuń wiodący znak
?
z elementuQuery string
, aby użyć wartości jako sekretu podczas tworzenia poświadczeń o zakresie bazy danych.
Wyświetlaj i pobieraj rozszerzone pliki zdarzeń z kontenera blob.
Pobierz Eksplorator usługi Azure Storage.
Powiązana zawartość
- Zrozumienie i rozwiązywanie problemów z blokowaniem
- Przewodnik blokowania transakcji i wersjonowania wierszy
- Przewodnik zakleszczenia
- USTAW POZIOM IZOLACJI TRANSAKCJI
- Azure SQL Database: zwiększanie dostrajania wydajności za pomocą automatycznego dostrajania
- Zapewnianie spójnej wydajności za pomocą usługi Azure SQL
- logika ponawiania prób dla błędów przejściowych