Delen via


Deadlocks in Azure SQL Database en Fabric SQL-database analyseren en voorkomen

van toepassing op:Azure SQL DatabaseSQL-database in Fabric

In dit artikel leert u hoe u impasses kunt identificeren, impassegrafieken en Query Store kunt gebruiken om de query's in de impasse te identificeren en wijzigingen te plannen en te testen om te voorkomen dat impasses opnieuw voorkomen. Dit artikel is van toepassing op Azure SQL Database en Fabric SQL Database, die veel functies van Azure SQL Database deelt.

Dit artikel is gericht op het identificeren en analyseren van deadlocks vanwege lock-contentie. Meer informatie over andere soorten vastlopingen in bronnen die vast kunnen lopen.

Hoe impasses optreden

Voor elke nieuwe database in Azure SQL Database is standaard de de instelling voor vastgelegde isolatie van momentopnamen (RCSI) ingeschakeld. Het blokkeren van tussen sessies die gegevens lezen en sessies die gegevens schrijven, wordt geminimaliseerd onder RCSI, waarbij gebruik wordt gemaakt van rijversiebeheer om gelijktijdigheid te verhogen. Blokkeringen en impasses kunnen echter nog steeds voorkomen in databases in Azure SQL Database, omdat:

  • Query's die gegevens wijzigen, kunnen elkaar blokkeren.

  • Query's kunnen worden uitgevoerd onder isolatieniveaus die de blokkering verhogen. Isolatieniveaus kunnen worden opgegeven via clientbibliotheekmethoden, queryhintsof SET TRANSACTION ISOLATION LEVEL in Transact-SQL.

  • RCSI kan mogelijk worden uitgeschakeld, waardoor de database gedeelde (S)-vergrendelingen gebruikt om SELECT instructies te beschermen die worden uitgevoerd onder het lees-gecommitteerd isolatieniveau. Dit kan leiden tot blokkeringen en impasses.

Een voorbeeld van een impasse

Er treedt een impasse op wanneer twee of meer taken elkaar permanent blokkeren, omdat elke taak een vergrendeling heeft op een resource die de andere taak probeert te vergrendelen. Een impasse wordt ook wel een cyclische afhankelijkheid genoemd: in het geval van een impasse met twee taken heeft transactie A een afhankelijkheid van transactie B en transactie B sluit de cirkel door een afhankelijkheid van transactie A te hebben.

Bijvoorbeeld:

  1. Sessie A begint met een expliciete transactie en voert een update-instructie uit die een updatevergrendeling (U) verkrijgt op één rij in tabel SalesLT.Product, welke wordt geconverteerd naar een exclusieve (X)-vergrendeling.

  2. sessie B voert een update-instructie uit waarmee de SalesLT.ProductDescription tabel wordt gewijzigd. De update-instructie wordt samengevoegd met de SalesLT.Product tabel om de juiste rijen te vinden die moeten worden bijgewerkt.

    • Sessie B krijgt een updatevergrendeling (U) op 72 rijen in de SalesLT.ProductDescription tabel.

    • Sessie B moet een gedeelde vergrendeling hebben op rijen in de tabel SalesLT.Product, inclusief de rij die is vergrendeld door Sessie A. Sessie B wordt geblokkeerd op SalesLT.Product.

  3. Sessie A, zet de transactie voort en voert nu een update uit op de SalesLT.ProductDescription-tabel. sessie A wordt geblokkeerd door sessie B op SalesLT.ProductDescription.

diagram met twee sessies in een impasse. Elke sessie is eigenaar van een resource die het andere proces nodig heeft om door te gaan.

Alle transacties in een impasse wachten voor onbepaalde tijd, tenzij een van de deelnemende transacties wordt teruggedraaid, bijvoorbeeld omdat de sessie is beëindigd.

De deadlockmonitor van de database-engine controleert periodiek taken die zich in een impasse bevinden. Als de impassemonitor een cyclische afhankelijkheid detecteert, kiest deze één van de taken als 'slachtoffer' en beëindigt diens transactie met fout 1205: Transaction (Process ID <N>) was deadlocked on lock resources with another process and is chosen as the deadlock victim. Rerun the transaction.. Door de impasse op deze manier te verbreken, stelt het de overige taak of taken in staat hun transacties te voltooien.

Notitie

Meer informatie over de criteria voor het kiezen van een impasseslachtoffer in de lijst met impasseprocessen sectie van dit artikel.

diagram van een impasse tussen twee sessies. Eén sessie wordt gekozen als het impasseslachtoffer.

De toepassing met de transactie die als het slachtoffer van de impasse is gekozen, moet de transactie opnieuw proberen, die meestal wordt voltooid nadat de andere transactie of transacties die betrokken zijn bij de impasse zijn voltooid.

Het is een best practice om een korte, gerandomiseerde vertraging te introduceren voordat u opnieuw probeert te voorkomen dat dezelfde impasse opnieuw optreedt. Meer informatie over het ontwerpen van de logica voor herhaald proberen bij tijdelijke fouten.

Standaardisolatieniveau in Azure SQL Database

Voor nieuwe databases in Azure SQL Database is standaard rcsi (read committed snapshot) ingeschakeld. RCSI wijzigt het gedrag van het lezen-gecommitteerde isolatieniveau om regelversiebeheer te gebruiken om consistentie op verklaringsniveau te bieden zonder dat er gedeelde (S)-vergrendelingen worden gebruikt voor SELECT verklaringen.

Met RCSI ingeschakeld:

  • Instructies die gegevens lezen, blokkeren geen instructies voor het wijzigen van gegevens.
  • Instructies die gegevens wijzigen, blokkeren geen instructies voor het lezen van gegevens.

isolatieniveau voor momentopnamen is ook standaard ingeschakeld voor nieuwe databases in Azure SQL Database. Isolatie van momentopnamen is een extra isolatieniveau op basis van rijen dat consistentie op transactieniveau biedt voor gegevens en waarbij rijversies worden gebruikt om rijen te selecteren die moeten worden bijgewerkt. Als u isolatie van momentopnamen wilt gebruiken, moeten query's of verbindingen het niveau van de transactieisolatie expliciet instellen op SNAPSHOT. Dit kan alleen worden gedaan wanneer isolatie van momentopnamen is ingeschakeld voor de database.

U kunt bepalen of RCSI en/of momentopname-isolatie zijn ingeschakeld met Transact-SQL. Maak verbinding met uw database in Azure SQL Database en voer de volgende query uit:

SELECT name,
       is_read_committed_snapshot_on,
       snapshot_isolation_state_desc
FROM sys.databases
WHERE name = DB_NAME();
GO

Als RCSI is ingeschakeld, retourneert de kolom is_read_committed_snapshot_on de waarde 1. Als isolatie van momentopnamen is ingeschakeld, retourneert de kolom snapshot_isolation_state_desc de waarde ON.

Als RCSI is uitgeschakeld voor een database in Azure SQL Database, onderzoekt u waarom RCSI is uitgeschakeld voordat u deze opnieuw inschakelt. Toepassingscode kan verwachten dat query's die gegevens lezen, worden geblokkeerd door query's die gegevens schrijven, wat resulteert in onjuiste resultaten van racevoorwaarden wanneer RCSI is ingeschakeld.

Impasse-gebeurtenissen interpreteren

Er wordt een impasse-gebeurtenis verzonden nadat de impassemanager in Azure SQL Database een impasse detecteert en een transactie als slachtoffer selecteert. Met andere woorden, als u waarschuwingen instelt voor impasses, wordt de melding geactiveerd nadat een afzonderlijke impasse is opgelost. Er is geen gebruikersactie die moet worden uitgevoerd voor die impasse. Toepassingen moeten worden geschreven om logica voor opnieuw proberen op te nemen, zodat ze automatisch doorgaan na ontvangst van fout 1205: Transaction (Process ID <N>) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Het is handig om waarschuwingen in te stellen, hoewel impasses opnieuw kunnen optreden. Met impassewaarschuwingen kunt u onderzoeken of er een patroon van herhalende impasses in uw database plaatsvindt. In dat geval kunt u ervoor kiezen om actie te ondernemen om te voorkomen dat impasses opnieuw optreden. Meer informatie over waarschuwingen in de sectie Monitor en waarschuwingen over impasses in sectie van dit artikel.

Belangrijkste methoden om impasses te voorkomen

De laagste risicobenadering om te voorkomen dat impasses opnieuw optreden, is over het algemeen om niet-geclusterde indexen af te stemmen om query's die betrokken zijn bij de impasse te optimaliseren.

  • Het risico is laag voor deze aanpak omdat het afstemmen van niet-geclusterde indexen geen wijzigingen in de querycode zelf vereist, waardoor het risico van een gebruikersfout wordt verminderd bij het herschrijven van Transact-SQL waardoor onjuiste gegevens naar de gebruiker worden geretourneerd.

  • Effectieve niet-geclusterde indexafstemming helpt query's de gegevens te vinden die efficiënter kunnen worden gelezen en gewijzigd. Door de hoeveelheid gegevens te verminderen waartoe een query toegang nodig heeft, wordt de kans op blokkeren verminderd en kunnen impasses vaak worden voorkomen.

In sommige gevallen kan het maken of optimaliseren van een geclusterde index het blokkeren en impasses verminderen. Omdat de geclusterde index is opgenomen in alle niet-geclusterde indexdefinities, kan het maken of wijzigen van een geclusterde index een I/O-intensieve en tijdrovende bewerking zijn voor grotere tabellen met bestaande niet-geclusterde indexen. Meer informatie over ontwerprichtlijnen voor geclusterde indexen.

Wanneer indexafstemming niet succesvol is in het voorkomen van deadlocks, zijn er andere methoden beschikbaar:

  • Als de impasse alleen optreedt wanneer een bepaald plan wordt gekozen voor een van de query's die betrokken zijn bij de impasse, het afdwingen van een queryplan met Query Store kan voorkomen dat impasses opnieuw optreden.

  • Het herschrijven van Transact-SQL voor een of meer transacties in de impasse kan ook helpen impasses te voorkomen. Het splitsen van expliciete transacties in kleinere transacties vereist zorgvuldig coderen en testen om ervoor te zorgen dat gegevens geldig zijn wanneer gelijktijdige wijzigingen plaatsvinden.

Meer informatie over elk van deze benaderingen vindt u in de Voorkomen dat er een impasse optreedt sectie van dit artikel.

Bewaken en waarschuwen bij deadlocks

In dit artikel gebruiken we de AdventureWorksLT voorbeelddatabase om waarschuwingen in te stellen voor impasses, een voorbeeld van een impasse te veroorzaken, de impassegrafiek voor het voorbeeld van een impasse te analyseren en wijzigingen te testen om te voorkomen dat de impasse opnieuw optreedt.

In dit artikel gebruiken we de SSMS-client (SQL Server Management Studio), omdat deze functionaliteit bevat voor het weergeven van impassegrafieken in een interactieve visuele modus. U kunt andere clients zoals Azure Data Studio gebruiken om de voorbeelden te volgen, maar mogelijk kunt u alleen impassegrafieken weergeven als XML.

De AdventureWorksLT-database maken

Als u de voorbeelden wilt volgen, maakt u een nieuwe database in Azure SQL Database en selecteert u Voorbeeldgegevens als de gegevensbron.

Voor gedetailleerde instructies over het maken van AdventureWorksLT met Azure Portal, Azure CLI of PowerShell selecteert u de methode van uw keuze in quickstart: Een individuele Azure SQL Database-database maken.

Impassewaarschuwingen instellen in Azure Portal

Als u waarschuwingen wilt instellen voor impasse-gebeurtenissen, volgt u de stappen in het artikel Waarschuwingen maken voor Azure SQL Database en Azure Synapse Analytics met behulp van de Azure-portal.

Kies deadlocks als de naam van het signaal voor deze waarschuwing. Configureer de actiegroep zodat u op de door u gewenste manier op de hoogte wordt gesteld, zoals het actietype e-mail/SMS/push/spraak .

Impassegrafieken verzamelen in Azure SQL Database met uitgebreide gebeurtenissen

Impassegrafieken zijn een rijke bron van informatie over de processen en vergrendelingen die betrokken zijn bij een impasse. Als u impassegrafieken wilt verzamelen met uitgebreide gebeurtenissen (XEvents) in Azure SQL Database, legt u de sqlserver.database_xml_deadlock_report gebeurtenis vast.

U kunt impassegrafieken met XEvents verzamelen met behulp van het ringbufferdoel of een gebeurtenisbestandsdoel. Overwegingen voor het selecteren van het juiste doeltype worden samengevat in de volgende tabel:

Aanpak Voordelen Overwegingen Gebruiksscenario's
Ringbufferdoel - Eenvoudige installatie met alleen Transact-SQL. - Gebeurtenisgegevens worden gewist wanneer de XEvents-sessie om welke reden dan ook wordt gestopt, zoals het offline halen van de database of een failover van een database.

- Databasebronnen worden gebruikt om gegevens in de ringbuffer te onderhouden en om sessiegegevens op te vragen.
- Verzamel voorbeeldtraceringsgegevens voor testen en leren.

- Maak voor kortetermijnbehoeften als u een sessie niet direct kunt instellen met behulp van een event-bestand als doel.

- Gebruik als een landingspad voor traceringsgegevens, wanneer u een geautomatiseerd proces hebt ingesteld om traceringsgegevens in een tabel op te slaan.
Bestemming van gebeurtenisbestand - Bewaart gebeurtenisgegevens naar een blob in Azure Storage, zodat gegevens beschikbaar zijn, zelfs nadat de sessie is gestopt.

- Gebeurtenisbestanden kunnen worden gedownload vanuit De Azure-portal of Azure Storage Explorer en lokaal worden geanalyseerd. Hiervoor hoeft u geen databasebronnen te gebruiken om query's uit te voeren op sessiegegevens.
- De setup is ingewikkelder en vereist de configuratie van een Azure Storage-container en een database-bereik gegevens. - Algemeen gebruik wanneer u wilt dat gebeurtenisgegevens behouden blijven, zelfs nadat de gebeurtenissessie is gestopt.

- U wilt een tracering uitvoeren die grotere hoeveelheden gebeurtenisgegevens genereert dan u wilt behouden in het geheugen.

Selecteer het doeltype dat u wilt gebruiken:

Het ringbufferdoel is handig en eenvoudig in te stellen, maar heeft een beperkte capaciteit, waardoor oudere gebeurtenissen verloren kunnen gaan. De ringbuffer bewaart geen gebeurtenissen voor opslag en het ringbufferdoel wordt gewist wanneer de XEvents-sessie wordt gestopt. Dit betekent dat alle verzamelde XEvents niet beschikbaar zijn wanneer de database-engine om welke reden dan ook opnieuw wordt opgestart, zoals een failover. Het ringbufferdoel is het meest geschikt voor leer- en kortetermijnbehoeften als u niet onmiddellijk een XEvents-sessie kunt instellen op een gebeurtenisbestandsdoel.

Met deze voorbeeldcode wordt een XEvents-sessie gemaakt waarmee impassegrafieken in het geheugen worden vastgelegd met behulp van het ringbufferdoel. Het maximale geheugen dat is toegestaan voor het ringbufferdoel is 4 MB en de sessie wordt automatisch uitgevoerd wanneer de database online komt, bijvoorbeeld na een failover.

Als u een XEvents-sessie wilt maken en starten voor de sqlserver.database_xml_deadlock_report gebeurtenis die naar het ringbufferdoel schrijft, maakt u verbinding met uw database en voert u de volgende Transact-SQL uit:

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

Een impasse veroorzaken in AdventureWorksLT

Notitie

Dit voorbeeld werkt in de AdventureWorksLT-database met het standaardschema en de standaardgegevens wanneer RCSI is ingeschakeld. Zie De AdventureWorksLT-database maken voor instructies voor het maken van de database.

Als u een impasse wilt veroorzaken, moet u twee sessies verbinden met de AdventureWorksLT-database. We verwijzen naar deze sessies als sessie A en sessie B.

Voer in Sessie Ade volgende Transact-SQL uit. Deze code begint met een expliciete transactie en voert één instructie uit waarmee de SalesLT.Product tabel wordt bijgewerkt. Hiervoor verkrijgt de transactie een update (U)-vergrendeling op één rij in tabel SalesLT.Product die wordt geconverteerd naar een exclusieve (X)-vergrendeling. We laten de transactie openstaan.

BEGIN TRANSACTION;

UPDATE SalesLT.Product
SET SellEndDate = SellEndDate + 1
WHERE Color = 'Red';

Voer nu in Sessie Bde volgende Transact-SQL uit. Deze code begint niet expliciet met een transactie. In plaats daarvan werkt het in autocommit transactiemodus. Met deze instructie wordt de tabel SalesLT.ProductDescription bijgewerkt. Met de update wordt een updatevergrendeling (U) uitgeschakeld op 72 rijen in de SalesLT.ProductDescription tabel. De query wordt samengevoegd met andere tabellen, inclusief de SalesLT.Product tabel.

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';

Om deze update te voltooien, moet sessie B een gedeelde vergrendeling (S) hebben op rijen in de tabel SalesLT.Product, inclusief de rij die is vergrendeld door Sessie A. sessie B wordt geblokkeerd op SalesLT.Product.

Ga terug naar sessie A. Voer de volgende Transact-SQL-instructie uit. Hiermee wordt een tweede UPDATE-instructie uitgevoerd als onderdeel van de open transactie.

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';

De tweede update-instructie in Sessie A- wordt geblokkeerd door Sessie B- op de SalesLT.ProductDescription.

Sessie A en Sessie B blokkeren elkaar nu wederzijds. Geen van beide transacties kan doorgaan, omdat ze elk een resource nodig hebben die door de andere is vergrendeld.

Na een paar seconden identificeert de impassemonitor dat de transacties in sessie A en sessie B elkaar wederzijds blokkeren en dat geen van beide vooruitgang kan boeken. U ziet dat er een impasse optreedt, waarbij Sessie A wordt gekozen als het impasseslachtoffer. Er wordt een foutbericht weergegeven in Sessie A met tekst die er ongeveer als volgt uitziet:

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.

sessie B is succesvol voltooid.

Als u waarschuwingen voor impasses instellen in Azure Portal, ontvangt u kort nadat de impasse is opgetreden een melding.

Impassegrafieken van een XEvents-sessie weergeven

Als u een XEvents-sessie instelt om impasses te verzamelen en er een impasse optreedt nadat de sessie is gestart, kunt u een interactieve grafische weergave van de impassegrafiek en de XML voor de impassegrafiek bekijken.

Er zijn verschillende methoden beschikbaar om impassegegevens te verkrijgen voor het ringbufferdoel en gebeurtenisbestandsdoelen. Selecteer het doel dat u hebt gebruikt voor uw XEvents-sessie:

Als u een XEvents-sessie instelt die naar de ringbuffer wordt geschreven, kunt u impassegegevens opvragen met de volgende Transact-SQL. Voordat u de query uitvoert, vervangt u de waarde van @tracename door de naam van uw XEvents-sessie.

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

Een impassegrafiek weergeven en opslaan in XML

Door een impassegrafiek in XML-indeling te bekijken, kunt u de inputbuffer van Transact-SQL instructies kopiëren die betrokken zijn bij de impasse. U kunt ook impasses in een tekstformaat analyseren.

Als u een Transact-SQL query hebt gebruikt om impassegrafiekgegevens te retourneren, selecteert u de waarde in de kolom deadlock_xml in een willekeurige rij om de XML van de impassegrafiek te openen in een nieuw venster in SSMS.

De XML voor deze voorbeeld impassegrafiek is:

<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>

De impassegrafiek opslaan als een XML-bestand:

  1. Selecteer Bestand en Opslaan als....
  2. Laat de Opslaan als waarde als de standaardwaarde XML-bestanden (*.xml)
  3. Stel de bestandsnaam in op een naam van uw keuze.
  4. Selecteer opslaan.

Een impassegrafiek opslaan als een XDL-bestand dat interactief kan worden weergegeven in SSMS

Het weergeven van een interactieve weergave van een impassegrafiek kan handig zijn om een kort overzicht te krijgen van de processen en resources die betrokken zijn bij een impasse en het snel identificeren van het impasseslachtoffer.

Een impassegrafiek opslaan als een bestand dat grafisch kan worden weergegeven door SSMS:

  1. Selecteer de waarde in de kolom deadlock_xml in een willekeurige rij om de XML van de impassegrafiek te openen in een nieuw venster in SSMS.

  2. Selecteer Bestand en Opslaan als....

  3. Stel Opslaan als in op alle bestanden.

  4. Stel de bestandsnaam in op de naam van uw keuze, waarbij de extensie is ingesteld op .xdl.

  5. Selecteer opslaan.

    Schermopname in SSMS van het opslaan van een deadlock graph XML-bestand in een bestand met de xsd-extensie.

  6. Sluit het bestand door de X op het tab bovenaan het venster te selecteren, of door Bestandte selecteren en vervolgens Sluiten.

  7. Open het bestand opnieuw in SSMS door Bestandte selecteren en Openen Bestand. Selecteer het bestand dat u hebt opgeslagen met de extensie .xdl.

    De impassegrafiek wordt nu weergegeven in SSMS met een visuele weergave van de processen en resources die betrokken zijn bij de impasse.

    Schermopname van een XDL-bestand dat is geopend in SSMS. De impassegrafiek wordt grafisch weergegeven, met processen die worden aangegeven door ovalen en resources vergrendelen als rechthoeken.

Een impasse analyseren voor Azure SQL Database

Een impassegrafiek heeft doorgaans drie knooppunten:

  • slachtoffers lijst. De procesidentificatie van het deadlockslachtoffer.

  • proceslijst. Informatie over alle processen die betrokken zijn bij de impasse. Impassegrafieken gebruiken de term 'proces' om een sessie weer te geven waarop een transactie wordt uitgevoerd.

  • Resource-lijst. Informatie over de resources die betrokken zijn bij de impasse.

Bij het analyseren van een impasse is het handig om deze knooppunten te doorlopen.

Lijst met slachtoffers van impasses

De lijst met impasseslachtoffers toont het proces dat is gekozen als het impasseslachtoffer. In de visuele weergave van een impassegrafiek worden processen weergegeven door ovalen. Het impasseslachtofferproces heeft een "X" getekend over het ovaal.

Schermopname van de visuele weergave van een impasse. Het ovaal dat het proces vertegenwoordigt dat als slachtoffer is geselecteerd, heeft er een X over getekend.

In de XML-weergave van een impassegrafiekgeeft het victim-list knooppunt een id voor het proces dat het slachtoffer was van de impasse.

In ons voorbeeld van een deadlock is de slachtofferproces-id process24756e75088. We kunnen deze id gebruiken bij het onderzoeken van de proceslijst- en resourcelijstknooppunten voor meer informatie over het slachtofferproces en de resources die het vergrendelen of aanvragen om te vergrendelen.

Lijst met impasseprocessen

De lijst met impasseprocessen is een uitgebreide bron van informatie over de transacties die betrokken zijn bij de impasse.

In de grafische weergave van de impassegrafiek ziet u slechts een subset met informatie in de XML van de impassegrafiek. De ovalen in de impassegrafiek vertegenwoordigen het proces en geven informatie weer, waaronder:

  • Sessie-id, ook wel bekend als de SPID.

  • Deadlock prioriteit van de sessie. Als twee sessies verschillende impasseprioriteiten hebben, wordt de sessie met de lagere prioriteit gekozen als het impasseslachtoffer. In dit voorbeeld hebben beide sessies dezelfde impasseprioriteit.

  • De hoeveelheid transactielogboek die door de sessie in bytes wordt gebruikt. Als beide sessies dezelfde impasseprioriteit hebben, kiest de impassemonitor de sessie die minder duur is om terug te draaien als het impasseslachtoffer. De kosten worden bepaald door het aantal logboekbytes te vergelijken, dat tot dat moment in elke transactie is geschreven.

    In ons voorbeeld met deadlock, had session_id 89 een lagere hoeveelheid transactielogboek gebruikt en werd geselecteerd als het deadlock-slachtoffer.

Daarnaast kunt u door de muisaanwijzer over elk proces te bewegen, de invoerbuffer bekijken voor de laatste instructie die in elke sessie vóór de impasse werd uitgevoerd. De invoerbuffer verschijnt in een tooltip.

Schermopname van een impassegrafiek die visueel wordt weergegeven in SSMS. Twee ovalen vertegenwoordigen processen. De invoerbuffer voor één proces wordt weergegeven.

Aanvullende informatie is beschikbaar voor processen in de XML-weergave van de impassegrafiek, waaronder:

  • Identificatiegegevens voor de sessie, zoals de clientnaam, hostnaam en aanmeldingsnaam.

  • De hash van het queryplan voor de laatste verklaring die door elke sessie is uitgevoerd vóór de impasse. De hash van het queryplan is handig voor het ophalen van meer informatie over de query uit Query Store.

In ons voorbeeld impasse:

  • We kunnen zien dat beide sessies zijn uitgevoerd met behulp van de SSMS-client onder de chrisqpublic aanmelding.

  • De queryplan-hash van de laatste instructie uitgevoerd door ons deadlockslachtoffer vóór de deadlock is 0x02b0f58d7730f798. De tekst van deze instructie wordt weergegeven in de invoerbuffer.

  • De queryplan-hash van de laatste instructie uitgevoerd door de andere sessie in onze impasse, is eveneens 0x02b0f58d7730f798. De tekst van deze instructie wordt weergegeven in de invoerbuffer. In dit geval hebben beide query's dezelfde hash van het queryplan, omdat de query's identiek zijn, met uitzondering van een letterlijke waarde die wordt gebruikt als gelijkheidspredicaat.

We gebruiken deze waarden verderop in dit artikel om aanvullende informatie te vinden in Query Store.

Beperkingen van de invoerbuffer in de lijst met impasseprocessen

Er zijn enkele beperkingen om rekening mee te houden met betrekking tot informatie over invoerbuffers in de lijst met impasseprocessen.

Querytekst kan worden afgekapt in de invoerbuffer. De invoerbuffer is beperkt tot de eerste 4000 tekens van de instructie die wordt uitgevoerd.

Daarnaast zijn sommige verklaringen die betrokken zijn bij de impasse mogelijk niet opgenomen in de impassegrafiek. In ons voorbeeld heeft Sessie A twee update-instructies uitgevoerd binnen één transactie. Alleen de tweede update-instructie, de update die de impasse heeft veroorzaakt, wordt opgenomen in de impassegrafiek. De eerste update-instructie uitgevoerd door Sessie A speelde een rol in de impasse door Sessie Bte blokkeren. De invoerbuffer, query_hash, en andere relevante informatie voor de eerste instructie uitgevoerd door Sessie A is niet opgenomen in de deadlock-grafiek.

Als u de volledige Transact-SQL wilt identificeren die is uitgevoerd in een transactie met meerdere instructies die betrokken zijn bij een impasse, moet u ofwel de relevante informatie vinden in de opgeslagen procedure of toepassingscode waarmee de query is uitgevoerd, of een tracering uitvoeren met behulp van Uitgebreide Gebeurtenissen om volledige instructies vast te leggen die tijdens een impasse door sessies worden uitgevoerd. Als een instructie die betrokken is bij de impasse wordt afgekapt en slechts gedeeltelijk Transact-SQL in de invoerbuffer wordt weergegeven, kunt u de Transact-SQL voor de instructie vinden in Query Store met het uitvoeringsplan.

Lijst met deadlockbronnen

In de lijst met impasseresources ziet u welke vergrendelingsresources eigendom zijn van de processen in de impasse en op gewacht wordt door deze processen.

Resources worden weergegeven door rechthoeken in de visuele weergave van de impasse:

Schermopname van een impassegrafiek die visueel wordt weergegeven in SSMS. Rechthoeken geven de resources weer die betrokken zijn bij de impasse.

Notitie

Databasenamen worden weergegeven als GUID's (uniqueidentifier) in impassegrafieken voor databases in Azure SQL Database. Dit is de physical_database_name voor de database die wordt vermeld in de sys.databases en sys.dm_user_db_resource_governance dynamische beheerweergaven.

In dit voorbeeld impasse:

  • Het slachtoffer van de deadlock, waarnaar we hebben verwezen als Sessie A:

    • Bezit een exclusieve (X)-vergrendeling voor een sleutel op de PK_Product_ProductID-index in de SalesLT.Product-tabel.

    • Vraagt om een updatevergrendeling (U) voor een sleutel op de PK_ProductDescription_ProductDescriptionID-index in de SalesLT.ProductDescription tabel.

  • Het andere proces, waarnaar we hebben verwezen als sessie B:

    • Heeft een updatevergrendeling (U) op een sleutel op de PK_ProductDescription_ProductDescriptionID-index op de SalesLT.ProductDescription-tabel.

    • Hiermee wordt een gedeelde (S)-vergrendeling aangevraagd op een sleutel in de PK_ProductDescription_ProductDescriptionID-index van de SalesLT.ProductDescription-tabel.

We kunnen dezelfde informatie zien in de XML van de impassegrafiek in het knooppunt resourcelijst.

Query-uitvoeringsplannen zoeken in de Query Store

Het is vaak nuttig om de uitvoeringsplannen voor query's en instructies te onderzoeken die betrokken zijn bij de impasse. Deze uitvoeringsplannen zijn vaak te vinden in Query Store met behulp van de hash van het queryplan uit de XML-weergave van de proceslijst van de impassegrafiek.

Deze Transact-SQL query zoekt naar queryplannen die overeenkomen met de hash van het queryplan die we hebben gevonden voor onze voorbeeld-impasse. Maak verbinding met de gebruikersdatabase in Azure SQL Database om de query uit te voeren.

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

Mogelijk kunt u geen queryuitvoeringsplan ophalen uit Query Store, afhankelijk van uw Query Store-CLEANUP_POLICY of QUERY_CAPTURE_MODE instellingen. In dit geval kunt u vaak de benodigde informatie verkrijgen door het geschatte uitvoeringsplan weer te geven voor de query.

Zoeken naar patronen die de blokkering vergroten

Wanneer u queryuitvoeringsplannen onderzoekt die betrokken zijn bij impasses, kijkt u naar patronen die kunnen bijdragen aan blokkeringen en impasses.

  • Tabel- of indexscans. Wanneer query's die gegevens wijzigen, worden uitgevoerd onder RCSI, wordt de selectie van rijen die moeten worden bijgewerkt uitgevoerd met behulp van een blokkerende scan waarbij een updatevergrendeling (U) wordt uitgevoerd op de gegevensrij wanneer gegevenswaarden worden gelezen. Als de gegevensrij niet voldoet aan de updatecriteria, wordt de updatevergrendeling vrijgegeven en wordt de volgende rij vergrendeld en gescand.

    Door indexen af te stemmen om modificatiequery's efficiënter rijen te laten vinden, wordt het aantal uitgegeven updatevergrendelingen verminderd. Dit vermindert de kans op blokkeren en impasses.

  • geïndexeerde weergaven die verwijzen naar meer dan één tabel. Wanneer u een tabel wijzigt waarnaar wordt verwezen in een geïndexeerde weergave, moet de database-engine ook de geïndexeerde weergave behouden. Hiervoor moeten er meer vergrendelingen worden verwijderd en kan dit leiden tot meer blokkeringen en impasses. Geïndexeerde weergaven kunnen er ook toe leiden dat updatebewerkingen intern worden uitgevoerd onder het isolatieniveau voor lezen.

  • Wijzigingen in kolommen waarnaar wordt verwezen in foreign key-beperkingen. Wanneer u kolommen in een tabel wijzigt waarnaar wordt verwezen in een FOREIGN KEY beperking, moet de database-engine zoeken naar gerelateerde rijen in de verwijzende tabel. Rijversies kunnen niet worden gebruikt voor deze leesbewerkingen. In gevallen waarin cascade-updates of verwijderingen zijn ingeschakeld, kan het isolatieniveau worden geëscaleerd naar serialiseerbaar gedurende de uitvoering van de instructie om te beschermen tegen fantoominvoegingen.

  • Vergrendelingshints. Zoek naar tabelhints die isolatieniveaus opgeven waarvoor meer vergrendelingen nodig zijn. Deze hints omvatten HOLDLOCK (die gelijk is aan serialiseerbare), SERIALIZABLE, READCOMMITTEDLOCK (waarmee RCSI wordt uitgeschakeld) en REPEATABLEREAD. Daarnaast kunnen hints zoals PAGLOCK, TABLOCK, UPDLOCKen XLOCK de risico's van blokkeren en impasses verhogen.

    Als deze hints aanwezig zijn, onderzoekt u waarom de hints zijn geïmplementeerd. Deze hints kunnen racevoorwaarden voorkomen en ervoor zorgen dat gegevens geldig zijn. Het is mogelijk om deze hints op de plaats te laten en toekomstige impasses te voorkomen met behulp van een alternatieve methode in de Voorkomen dat een impasse opnieuw optreedt sectie van dit artikel, indien nodig.

    Notitie

    Meer informatie over gedrag bij het wijzigen van gegevens met behulp van rijversiebeheer in de handleiding voor het vergrendelen van transacties en het versiebeheer van rijen.

Wanneer u de volledige code voor een transactie bekijkt, hetzij in een uitvoeringsplan of in toepassingsquerycode, zoekt u naar aanvullende problematische patronen:

  • Gebruikersinteractie bij transacties. Gebruikersinteractie binnen een expliciete transactie met meerdere instructies verhoogt de duur van transacties aanzienlijk. Dit maakt het waarschijnlijker dat deze transacties elkaar overlappen en dat er blokkeringen en impasses optreden.

    Op dezelfde manier verhoogt het houden van een open transactie en het uitvoeren van query's op een niet-gerelateerde database of systeem mid-transaction de kans op blokkeringen en impasses aanzienlijk.

  • Transacties die toegang hebben tot objecten in verschillende volgorden. Impasses zijn minder waarschijnlijk wanneer gelijktijdige expliciete transacties met meerdere verklaringen dezelfde patronen volgen en objecten in dezelfde volgorde openen.

Voorkomen dat een impasse opnieuw optreedt

Er zijn meerdere technieken beschikbaar om te voorkomen dat deadlocks opnieuw optreden, zoals het afstemmen van indexen, het afdwingen van plannen met Query Store en het wijzigen van Transact-SQL queries.

  • Bekijk de geclusterde index van de tabel. De meeste tabellen profiteren van geclusterde indexen, maar vaak worden tabellen per ongeluk geïmplementeerd als heaps.

    Een manier om te controleren op een geclusterde index is door de sp_helpindex systeem-opgeslagen procedure te gebruiken. We kunnen bijvoorbeeld een samenvatting van de indexen in de SalesLT.Product tabel bekijken door de volgende instructie uit te voeren:

    EXECUTE sp_helpindex 'SalesLT.Product';
    GO
    

    Controleer de kolom index_description. Een tabel kan slechts één geclusterde index hebben. Als een geclusterde index voor de tabel is geïmplementeerd, bevat de index_description het woord clustered.

    Als er geen geclusterde index aanwezig is, is de tabel een heap. Controleer in dit geval of de tabel opzettelijk als een heap is gemaakt om een specifiek prestatieprobleem op te lossen. Overweeg om een geclusterde index te implementeren op basis van de richtlijnen voor het ontwerpen van geclusterde indexen.

    In sommige gevallen kan het maken of afstemmen van een geclusterde index blokkades tijdens doodlopende processen verminderen of elimineren. In andere gevallen kunt u een extra techniek gebruiken, zoals de andere in deze lijst.

  • niet-geclusterde indexen maken of wijzigen. Het afstemmen van niet-geclusterde indexen kan uw wijzigingsquery's helpen om de gegevens sneller te vinden, waardoor het aantal vereiste updatevergrendelingen wordt verminderd.

    In ons voorbeeld van een deadlock, bevat het queryuitvoeringsplan , gevonden in Query Store, een geclusterde indexscan tegen de PK_Product_ProductID index. De impassegrafiek geeft aan dat een gedeelde (S)-vergrendeling wacht op deze index een onderdeel is in de impasse.

    Schermopname van een queryuitvoeringsplan. Er wordt een geclusterde indexscan uitgevoerd op basis van de PK_Product_ProductID-index in de tabel Product.

    Deze indexscan wordt uitgevoerd omdat onze updatequery een geïndexeerde weergave met de naam vProductAndDescriptionmoet wijzigen. Zoals vermeld in het gedeelte Zoeken naar patronen die het blokkeren verhogen van dit artikel, kunnen geïndexeerde weergaven die naar meerdere tabellen verwijzen de blokkering en de kans op impasses vergroten.

    Als we de volgende niet-geclusterde index maken in de AdventureWorksLT-database die de kolommen 'bedekt' van SalesLT.Product waarnaar wordt verwezen door de geïndexeerde weergave, helpt dit de query veel efficiënter rijen te vinden:

    CREATE INDEX IX_Product_ProductID_Name_ProductModelID
        ON SalesLT.Product(ProductID, Name, ProductModelID);
    GO
    

    Nadat u deze index hebt gemaakt, treedt de impasse niet meer op.

    Wanneer impasses betrekking hebben op wijzigingen in kolommen waarnaar wordt verwezen in foreign key-beperkingen, moet u ervoor zorgen dat indexen op de verwijzende tabel van de FOREIGN KEY op efficiënte wijze gerelateerde rijen kunnen vinden.

    Hoewel indexen in sommige gevallen de queryprestaties aanzienlijk kunnen verbeteren, hebben indexen ook overhead- en beheerkosten. Bekijk algemene richtlijnen voor het ontwerpen van indexen om het voordeel van indexen te beoordelen voordat u indexen maakt, met name brede indexen en indexen op grote tabellen.

  • Evalueer de waarde van geïndexeerde weergaven. Een andere optie om te voorkomen dat onze impasse opnieuw voorkomt, is de SalesLT.vProductAndDescription-geïndexeerde weergave te laten vallen. Als deze geïndexeerde weergave niet wordt gebruikt, vermindert dit de overhead van het onderhouden van de geïndexeerde weergave in de loop van de tijd.

  • Momentopname-isolatie gebruiken. In sommige gevallen kan het niveau van transactieisolatie instellen op momentopname voor een of meer van de transacties die zijn betrokken bij een impasse, mogelijk voorkomen dat blokkeringen en impasses opnieuw optreden.

    Deze techniek is waarschijnlijk geslaagd wanneer deze wordt gebruikt voor SELECT instructies wanneer vastgelegde momentopname is uitgeschakeld in een database. Wanneer de 'read committed snapshot' is uitgeschakeld, vereisen SELECT-query's die gebruikmaken van het 'read committed' isolatieniveau gedeelde (S)-vergrendelingen. Als u isolatie van momentopnamen voor deze transacties gebruikt, hoeft u geen gedeelde vergrendelingen te gebruiken, waardoor blokkeren en impasses kunnen worden voorkomen.

    In databases waarvoor isolatie van vastgelegde momentopnamen is ingeschakeld, zijn voor SELECT query's geen gedeelde (S)-vergrendelingen vereist, waardoor de kans op deadlocks groter is tussen transacties die gegevens wijzigen. In gevallen waarin impasses optreden tussen meerdere transacties die gegevens wijzigen, kan isolatie van momentopnamen leiden tot een updateconflict in plaats van een impasse. Hiervoor is het nodig dat een van de transacties de bewerking opnieuw probeert uit te voeren.

  • Dwing een plan af met Query Store. Het kan zijn dat een van de query's in de impasse meerdere uitvoeringsplannen heeft en dat de impasse alleen optreedt wanneer een specifiek plan wordt gebruikt. U kunt voorkomen dat de impasse opnieuw optreedt door het afdwingen van een plan in Query Store.

  • Wijzig de Transact-SQL-. Mogelijk moet u Transact-SQL wijzigen om te voorkomen dat de impasse opnieuw optreedt. Het wijzigen van Transact-SQL moet zorgvuldig worden uitgevoerd en wijzigingen moeten grondig worden getest om ervoor te zorgen dat gegevens correct zijn wanneer wijzigingen gelijktijdig worden uitgevoerd. Overweeg het volgende bij het herschrijven van Transact-SQL:

    • Instructies ordenen in transacties om toegang te krijgen tot objecten in dezelfde volgorde.

    • Transacties opsplitsen in kleinere transacties wanneer mogelijk.

    • Gebruik zo nodig queryhints om de prestaties te optimaliseren. U kunt hints toepassen zonder toepassingscode te wijzigen met behulp van Query Store.

Vind meer manieren om impasses te minimaliseren in de gids impasses.

Notitie

In sommige gevallen kunt u de prioriteit van de impasse aanpassen voor een of meer sessies die betrokken zijn bij een impasse, vooral wanneer het belangrijk is dat een van de sessies succesvol wordt afgerond zonder dat een hernieuwde poging nodig is, of wanneer een van de query's die bij de impasse betrokken zijn niet cruciaal is en altijd als slachtoffer moet worden gekozen. Hoewel dit niet voorkomt dat de impasse opnieuw optreedt, kan dit het effect van toekomstige impasses verminderen.

Een XEvents-sessie verwijderen

U kunt een XEvents-sessie met het verzamelen van impassegegevens op kritieke databases gedurende lange perioden laten staan. Als u een logbestand als doel gebruikt, kan dit leiden tot grote bestanden als er meerdere impasses optreden. U kunt blobbestanden verwijderen uit Azure Storage voor een actieve trace, met uitzondering van het bestand waarnaar momenteel wordt geschreven.

Wanneer u een XEvents-sessie wilt verwijderen, is het Transact-SQL de sessie verwijderen hetzelfde, ongeacht het geselecteerde doeltype.

Als u een XEvents-sessie wilt verwijderen, voert u de volgende Transact-SQL uit. Voordat u de code uitvoert, vervangt u de naam van de sessie door de juiste waarde.

ALTER EVENT SESSION [deadlocks] ON DATABASE
STATE = STOP;
GO

DROP EVENT SESSION [deadlocks] ON DATABASE;
GO

Azure Storage Explorer gebruiken

Azure Storage Explorer is een zelfstandige toepassing waarmee u eenvoudiger kunt werken met gebeurtenisbestandsdoelen die zijn opgeslagen in blobs in Azure Storage. U kunt Storage Explorer gebruiken voor het volgende:

Azure Storage Explorer-downloaden.