Analizowanie i zapobieganie zakleszczeniom w usłudze Azure SQL Database i bazie danych SQL Fabric
Dotyczy:Baza danych SQL Usługi Azure SQL Databasew sieci szkieletowej
W tym artykule przedstawiono sposób identyfikowania zakleszczeń, używania wykresów zakleszczenia i magazynu zapytań do identyfikowania zapytań w impasie oraz planowania i testowania zmian, aby zapobiec ponownemu zakleszczeniu. 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ą zakleszczeć.
Jak występują zakleszczenia
Każda nowa baza danych w usłudze Azure SQL Database ma domyślnie włączone ustawienie bazy danych izolacji odczytu z zatwierdzonymi migawkami (RCSI). Blokowanie między sesjami odczytu danych i sesji zapisywania danych jest zminimalizowane w obszarze RCSI, co używa przechowywania wersji 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 co najmniej dwa zadania trwale blokują się nawzajem, ponieważ każde zadanie ma blokadę zasobu, który próbuje zablokować drugie zadanie. Zakleszczenie jest również nazywane cykliczną zależnością: w przypadku zakleszczenia dwóch zadań transakcja A ma zależność od transakcji B, a transakcja B zamyka koło, 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 zablokowania aparatu bazy danych okresowo sprawdza pod kątem zadań, które są blokowane. 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 wykonywanie innych zadań lub zadań w impasie w celu ukończenia transakcji.
Uwaga
Dowiedz się więcej o kryteriach wybierania ofiary zakleszczenia w sekcji lista procesów zakleszczenia w tym artykule.
Aplikacja z transakcją wybraną jako ofiara zakleszczenia powinna ponowić próbę transakcji, 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 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ść na poziomie transakcji dla danych i który używa wersji wierszy do wybierania wierszy do aktualizacji. Aby użyć izolacji migawki, zapytania lub połączenia muszą jawnie ustawić poziom izolacji transakcji na SNAPSHOT
wartość . Można to zrobić tylko wtedy, gdy dla bazy danych jest włączona izolacja migawki.
Możesz określić, czy izolacja RCSI i/lub migawki jest włączona w języku Transact-SQL. 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 zakleszczenia jest emitowane po wykryciu zakleszczenia przez menedżera zakleszczenia w usłudze Azure SQL Database i wybraniu transakcji jako ofiary. Innymi słowy, jeśli skonfigurujesz alerty dotyczące zakleszczeń, powiadomienie zostanie wysłane po rozwiązaniu pojedynczego zakleszczenia. Nie ma żadnych działań użytkownika, które należy podjąć w przypadku tego zakleszczenia. 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 którym 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
Najniższym podejściem do ryzyka zapobiegania zakleszczeniom z reoccurringu jest zazwyczaj dostrajanie 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 nieklastrowanych definicjach indeksu, tworzenie lub modyfikowanie indeksu klastrowanego może być operacją intensywnie korzystającą z operacji we/wy i czasochłonną operacją na większych tabelach z istniejącymi indeksami nieklastrowanym. 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ć ponowne zakleszczenie.
Ponowne zapisywanie języka Transact-SQL dla co najmniej jednej transakcji zaangażowanej w zakleszczenie może również pomóc w zapobieganiu zakleszczeniom. 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 zakleszczeniom w tym artykule.
Monitorowanie zakleszczeń i zgłaszanie alertów
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 funkcje wyświetlania grafów zakleszczenia w trybie interaktywnym. Możesz użyć innych klientów, takich jak Azure Data Studio, aby postępować zgodnie z przykładami, ale możesz wyświetlać wykresy zakleszczenia tylko jako 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 za AdventureWorksLT
pomocą witryny Azure Portal, interfejsu wiersza polecenia platformy Azure lub programu PowerShell, wybierz wybrane podejście w przewodniku Szybki start: Tworzenie pojedynczej bazy danych usługi Azure SQL Database.
Konfigurowanie alertów zakleszczenia w witrynie Azure Portal
Aby skonfigurować alerty dotyczące zdarzeń zakleszczenia, wykonaj kroki opisane w artykule Tworzenie alertów dla usług Azure SQL Database i Azure Synapse Analytics przy użyciu witryny Azure Portal.
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 zakleszczenia są bogatym źródłem informacji dotyczących procesów i blokad związanych z impasem. Aby zebrać wykresy zakleszczenia z zdarzeniami rozszerzonymi (XEvents) w usłudze Azure SQL Database, przechwyć sqlserver.database_xml_deadlock_report
zdarzenie.
Wykresy zakleszczenia można zbierać z elementami XEvents przy użyciu docelowego buforu pierścieniowego lub docelowego pliku 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 miejsca docelowego 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 elementy XEvent nie są dostępne w przypadku ponownego uruchomienia aparatu bazy danych ze względu na dowolny powód, taki jak przełączenie awaryjne. 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 przykładowy kod tworzy sesję XEvents, która przechwytuje wykresy zakleszczenia w pamięci przy użyciu docelowego buforu pierścienia. 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ć, a następnie uruchomić sesję XEvents dla sqlserver.database_xml_deadlock_report
zdarzenia, które zapisuje w docelowym buforze pierścienia, 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 uruchom następujące polecenie Języka Transact-SQL. Ten kod rozpoczyna jawną transakcję i uruchamia pojedynczą instrukcję, która aktualizuje tabelęSalesLT.Product
. W tym celu transakcja uzyskuje blokadęSalesLT.Product
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 automatycznej transakcji. Ta instrukcja aktualizuje tabelę SalesLT.ProductDescription
. Aktualizacja zakłada aktualizacyjną blokadę (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';
Druga instrukcja aktualizacji w sesji A jest blokowana 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. Powinna pojawić się impas, a sesja A wybrana jako ofiara zakleszczenia. 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.
W przypadku skonfigurowania alertów zakleszczenia w witrynie Azure Portal powinno zostać wyświetlone powiadomienie wkrótce po wystąpieniu zakleszczenia.
Wyświetlanie wykresów 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 zapisu w buforze pierścienia, możesz wykonywać zapytania dotyczące zakleszczenia przy użyciu następującego języka 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świetlanie i zapisywanie grafu zakleszczenia w formacie XML
Wyświetlanie wykresu zakleszczenia w formacie XML umożliwia skopiowanie inputbuffer
instrukcji języka Transact-SQL zaangażowanych w zakleszczenie. 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ć kod XML grafu zakleszczenia, wybierz wartość w deadlock_xml
kolumnie z dowolnego wiersza, aby otworzyć 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.
Zapisywanie grafu zakleszczenia jako pliku 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 impasem oraz szybkie identyfikowanie ofiary 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 pozycję Plik, a następnie otwórz, a następnie pozycję Plik. Wybierz zapisany plik z
.xdl
rozszerzeniem .Wykres zakleszczenia jest teraz wyświetlany w programie SSMS z wizualną reprezentacją procesów i zasobów zaangażowanych w zakleszczenie.
Analizowanie zakleszczenia dla usługi Azure SQL Database
Wykres zakleszczenia zwykle ma trzy węzły:
Lista ofiar. Identyfikator procesu ofiary zakleszczenia.
Lista procesów. Informacje na temat wszystkich procesów związanych z zakleszczeniem. Wykresy zakleszczenia używają terminu "proces" do reprezentowania sesji uruchamianej transakcji.
Lista zasobów. Informacje o zasobach powiązanych z zakleszczeniem.
Podczas analizowania zakleszczenia warto krok po kroku przeanalizować te węzły.
Lista ofiar zakleszczenia
Lista ofiar zakleszczenia pokazuje proces, który został wybrany jako ofiara impasu. W wizualnej reprezentacji grafu zakleszczenia procesy są reprezentowane przez owalny. Proces ofiary impasu ma "X" narysowany na owalnym.
W widoku XML grafuvictim-list
zakleszczenia 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 związanych z impasem.
Graficzna reprezentacja grafu zakleszczenia przedstawia tylko podzbiór informacji zawartych w grafie zakleszczenia XML. Owalny na wykresie zakleszczenia reprezentują proces i pokazują informacje, w tym:
Identyfikator sesji, znany również jako SPID.
Priorytet zakleszczenia sesji. Jeśli dwie sesje mają różne priorytety zakleszczenia, sesja o niższym priorytecie zostanie 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óra jest tańsza, aby wycofać się jako ofiara 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 widoku XML grafu zakleszczenia, w tym:
Identyfikowanie informacji dotyczących sesji, takich jak nazwa klienta, nazwa hosta i nazwa logowania.
Skrót planu zapytania dla ostatniej instrukcji, która została uruchomiona 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 w logowania
chrisqpublic
.Skrót planu zapytania związany z ostatnią instrukcją uruchomioną przed zakleszczeniem, w której uczestniczyła nasza ofiara 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 na liście procesów zakleszczenia
Istnieją pewne ograniczenia dotyczące informacji o buforze wejściowym na liście procesów 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ę sesji A odegrała rolę w impasie, blokując sesji B. Bufor wejściowy, query_hash
i powiązane informacje dotyczące pierwszej instrukcji uruchamianej przez sesji A nie są uwzględniane w grafie zakleszczenia.
Aby zidentyfikować pełne Transact-SQL uruchomienie w transakcji wieloinstrukcyjnej zaangażowanej w zakleszczenie, należy znaleźć odpowiednie informacje w procedurze składowanej lub kodzie aplikacji, które uruchomiły zapytanie, lub uruchomić ślad z 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 jest obcięta i w buforze wejściowym pojawia się tylko częściowa Transact-SQL, można znaleźć Transact-SQL instrukcji w magazynie zapytań z planem wykonywania.
Lista zasobów zakleszczenia
Lista zasobów zakleszczenia pokazuje, które zasoby blokady są własnością i czekane przez procesy w impasie.
Zasoby są reprezentowane przez prostokąty w wizualnej reprezentacji zakleszczenia:
Uwaga
Nazwy baz danych są reprezentowane jako identyfikatory GUID (uniqueidentifier) w grafach zakleszczenia dla baz danych w usłudze Azure SQL Database. Jest physical_database_name
to element bazy danych wymieniony w bazach danych sys.databases i sys.dm_user_db_resource_governance dynamicznych widokach zarządzania.
W tym przykładzie zakleszczenia:
Ofiara zakleszczenia, którą nazwaliśmy sesją 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
wSalesLT.ProductDescription
tabeli.
Drugi proces, który nazywamy sesją B:
Jest właścicielem blokady aktualizacji (U) na kluczu w indeksie
PK_ProductDescription_ProductDescriptionID
wSalesLT.ProductDescription
tabeli.Żąda blokady udostępnionej (S) na kluczu w indeksie
PK_ProductDescription_ProductDescriptionID
wSalesLT.ProductDescription
tabeli.
Te same informacje są widoczne w kodzie XML grafu zakleszczenia w węźle lista zasobów.
Znajdowanie planów wykonywania zapytań w magazynie zapytań
Często przydatne jest sprawdzenie planów wykonania zapytań dotyczących operacji związanych z zakleszczeniem. Te plany wykonywania można często znaleźć w magazynie zapytań przy użyciu skrótu planu zapytania z widoku XML listy procesów grafu zakleszczenia.
To zapytanie Transact-SQL wyszukuje plany zapytań pasujące do skrótu planu zapytania, który znaleźliśmy na potrzeby 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 obszarze RCSI, wybór wierszy do aktualizacji odbywa się przy użyciu skanowania blokującego, w którym blokada aktualizacji (U) jest wykonywana w wierszu 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 ułatwienia modyfikacji zapytań dotyczących znajdowania wierszy wydajniej 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 wyjęcie większej liczby blokad i może prowadzić do zwiększenia blokowania i zakleszczenia. Widoki indeksowane mogą również spowodować, że operacje aktualizacji są wykonywane wewnętrznie w ramach poziomu izolacji zatwierdzonej do odczytu.
Modyfikacje kolumn, do których odwołuje się ograniczenia 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 serializacji na czas wykonywania instrukcji, w celu ochrony przed wstawkami fantomowymi.Zablokuj wskazówki. 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ą w miejscu, badania, dlaczego wskazówki zostały wdrożone. 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 bardziej prawdopodobne jest, aby te transakcje nakładały się i blokowały i zakleszczenia.
Podobnie przechowywanie otwartej transakcji i wykonywanie zapytań względem niepowiązanej bazy danych lub systemowej transakcji w połowie transakcji znacznie zwiększa prawdopodobieństwo blokowania i zakleszczenia.
Transakcje uzyskiwania dostępu do obiektów w różnych zamówieniach. Zakleszczenia są mniej prawdopodobne, gdy równoczesne transakcje z wieloma instrukcjami są zgodne z tymi samymi wzorcami i dostępem do obiektów w tej samej kolejności.
Zapobieganie zakleszczeniom
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 indeks klastrowany tabeli. Większość tabel korzysta z indeksów klastrowanych, ale często tabele są implementowane w sposób przypadkowy.
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 jako sterta w celu rozwiązania określonego problemu 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 w wyszukiwaniu danych w celu szybszego aktualizowania zapytań modyfikacji, co zmniejsza liczbę wymaganych blokad aktualizacji.
W naszym przykładowym zakleszczeniu plan wykonywania zapytania znaleziony w magazynie zapytań zawiera skanowanie indeksu klastrowanego względem indeksu
PK_Product_ProductID
. Wykres zakleszczenia wskazuje, że współużytkowany (S) oczekiwanie na ten indeks 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 nie będzie już powtarzane.
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 zakleszczaniu naszego przykładowego
SalesLT.vProductAndDescription
zakleszczenia jest usunięcie widoku indeksowanego. 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 do migawki 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 migawki zatwierdzonej do odczytu jest wyłączona w bazie danych. 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 konieczność blokowania udostępnionych blokad, co może uniemożliwić blokowanie i zakleszczenia.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 wykonania jednej z transakcji, aby ponowić próbę wykonania operacji.Wymuś plan z magazynem zapytań. 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 magazynie zapytań.
Zmodyfikuj język Transact-SQL. Aby zapobiec ponownemu zakleszczeniu, może być konieczne zmodyfikowanie 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 magazynu zapytań.
Znajdź więcej sposobów zminimalizowania zakleszczeń w przewodniku Zakleszczenia.
Uwaga
W niektórych przypadkach można dostosować priorytet impasu co najmniej jednej sesji biorącej udział w impasie, jeśli ważne jest, aby jedna z sesji zakończyła się pomyślnie bez konieczności ponawiania, lub gdy jedno z zapytań zaangażowanych w impas nie jest krytyczne i powinno być zawsze oznaczane jako ofiara. To nie zapobiega ponownym zakleszczeniom, jednak może zmniejszyć wpływ przyszłych zakleszczeń.
Usuwanie sesji XEvents
Możesz pozostawić sesję XEvents, która zbiera informacje o zakleszczeniach, działającą na krytycznych bazach danych 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 obiektów blob z usługi Azure Storage podczas aktywnego śledzenia, z wyjątkiem pliku, do którego obecnie odbywa się zapis.
Jeśli chcesz usunąć sesję XEvents, sesja transact-SQL jest taka sama, 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. Za pomocą Eksplorator usługi Storage można wykonywać następujące czynności:
Utwórz kontener obiektów blob do przechowywania danych sesji XEvent.
Pobierz sygnaturę dostępu współdzielonego (SAS) dla kontenera obiektów blob.
Jak wspomniano w artykule Zbieranie wykresów zakleszczenia w usłudze Azure SQL Database z zdarzeniami rozszerzonymi, wymagane są uprawnienia do odczytu, zapisu i listy.
Usuń dowolny znak wiodący
?
zQuery string
elementu , aby użyć wartości jako wpisu tajnego podczas tworzenia poświadczeń o zakresie bazy danych.
Wyświetlanie i pobieranie rozszerzonych plików zdarzeń z kontenera obiektów blob.
Pobierz Eksplorator usługi Azure Storage.
Powiązana zawartość
- Zrozumienie i rozwiązywanie problemów z blokowaniem
- Przewodnik dotyczący blokowania transakcji i przechowywania wersji wierszy
- Przewodnik zakleszczenia
- USTAWIANIE POZIOMU 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