Warum wird diese RX-X-Sperre in Extended Events nicht angezeigt?


13

Das Problem

Ich habe ein paar Abfragen, die unter serialisierbarer Isolation eine RX-X-Sperre verursachen. Wenn ich jedoch Extended Events verwende, um die Sperrenerfassung zu überwachen, wird die RX-X-Sperrenerfassung nie angezeigt, sondern nur freigegeben. Woher kommt das?

Der Repro

Hier ist mein Tisch:

CREATE TABLE dbo.LockTest (
ID int identity,
Junk char(4)
)

CREATE CLUSTERED INDEX CX_LockTest --not unique!
ON dbo.LockTest(ID)

--preload some rows
INSERT dbo.LockTest
VALUES ('data'),('data'),('data')

Hier ist meine Problemcharge:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN

INSERT dbo.LockTest
VALUES ('bleh')

SELECT *
FROM dbo.LockTest
WHERE ID = SCOPE_IDENTITY()

--ROLLBACK

Ich überprüfe die von dieser Sitzung gehaltenen Sperren und sehe RX-X:

SELECT resource_type, request_mode, request_status, resource_description
FROM sys.dm_tran_locks
WHERE request_session_id = 72 --change SPID!

dm_tran_locks

Ich habe aber auch ein Extended Event am lock_acquiredund lock_released. Ich filtere es nach der entsprechenden zugehörigen Objekt-ID ... da ist kein RX-X.

Erweiterte Ereignisausgabe

Nach dem Ausführen des Rollbacks wird RX-X (LAST_MODE) veröffentlicht, obwohl es nie erworben wurde.

LAST_MODE

Was ich versucht habe

  • Ich habe mir alle Sperren in Extended Events angesehen - keine Filterung. Es wurden keine RX-X-Sperren erworben.

  • Ich habe auch Profiler ausprobiert: gleiche Ergebnisse (außer natürlich, dass der Name stimmt ... kein "LAST_MODE").

  • Ich habe die XE für Sperreneskalationen ausgeführt - sie ist nicht vorhanden.

  • Es gibt kein spezielles XE für Konvertierungen, aber ich konnte bestätigen, dass mindestens die Konvertierung von U in X-Sperre von erfasst wird lock_acquired

Bemerkenswert ist auch der RI-N, der zwar erworben, aber nie veröffentlicht wird. Meine derzeitige Hypothese lautet, dass der RX-X eine Konvertierungssperre ist, wie hier beschrieben . In meinem Stapel gibt es überlappende Tastensperren, die für die Konvertierung in Frage kommen, aber die RX-X-Sperre befindet sich nicht in der Konvertierungstabelle.

Woher kommt dieses Schloss und warum wird es nicht von Extended Events aufgenommen?

Antworten:


12

Die einzeilige Einfügung erhält eine X(exklusive) Sperre für die neue Zeile.

Die SELECTVersuche, eine RangeS-SSperre mit gemeinsam genutztem Bereich und gemeinsam genutztem Schlüssel ( ) zu erwerben .

Diese Anfrage wird vom lock_acquiredExtended Event als mode = gemeldet RS_S.

Es wird von der Profiler-Ereignisklasse Lock:Acquiredals Modus 13 ( LCK_M_RS_S) gemeldet .

Der angeforderte Modus wird mit dem vorhandenen exklusiven Sperrmodus in Lock::CalculateGrantModein kombiniert sqlmin.dll. Es gibt keinen kombinierten Modus von Range-Shared, Key Exclusive ( RangeS-X), daher ist das Ergebnis der Berechnung Range-Exclusive, Key Exclusive ( RangeX-X), was zufällig Modus 15 ist.

Die obige Berechnung des Grant-Modus wird unmittelbar vor der Generierung des erweiterten Ereignisses durch ausgeführt lck_ProduceExtendedEvent<XeSqlPkg::lock_acquired>. Nichtsdestotrotz protokollieren Profiler und Extended Events den angeforderten RangeS-S Modus und nicht den daraus resultierenden Sperrmodus RangeX-X. Dies widerspricht der eingeschränkten Dokumentation , in der es heißt:

Modus | int | Resultierender Modus, nachdem die Sperre erfasst wurde.

Die Modusspalte des erweiterten Ereignisses enthält überhaupt keine Dokumentation, und die Beschreibung in den Metadaten ist leer. Vielleicht war sich Microsoft selbst des Verhaltens nicht sicher.

Ich habe oft gedacht, dass es nützlicher wäre, wenn Sperrereignisse sowohl den angeforderten als auch den resultierenden Modus melden , aber das ist nicht das, was wir haben. Die derzeitige Anordnung macht es so gut wie unmöglich, das Erfassen und Freigeben von Sperren zu verfolgen und abzugleichen.

Es könnte ein guter Grund für die Meldung Sperren auf diese Weise sein. Wenn dies nicht Ihren Anforderungen entspricht, können Sie einen Support-Fall bei Microsoft eröffnen oder ein Azure Feedback-Element erstellen.


LAST_MODE

Der mysteriöse LAST_MODEist etwas Erik Darling vorhin bemerkt auf . Dies ist der höchste map_keyWert in der Liste der Sperrmodi, die angezeigt werden von sys.dm_xe_map_values:

SELECT
    DXMV.map_key,
    DXMV.map_value
FROM sys.dm_xe_map_values AS DXMV
WHERE 
    DXMV.[name] = N'lock_mode'
ORDER BY
    DXMV.map_key;
╔═════════╦═══════════╗
║ map_key ║ map_value ║
╠═════════╬═══════════╣
║       0 ║ NL        ║
║       1 ║ SCH_S     ║
║       2 ║ SCH_M     ║
║       3 ║ S         ║
║       4 ║ U         ║
║       5 ║ X         ║
║       6 ║ IS        ║
║       7 ║ IU        ║
║       8 ║ IX        ║
║       9 ║ SIU       ║
║      10 ║ SIX       ║
║      11 ║ UIX       ║
║      12 ║ BU        ║
║      13 ║ RS_S      ║
║      14 ║ RS_U      ║
║      15 ║ RI_NL     ║
║      16 ║ RI_S      ║
║      17 ║ RI_U      ║
║      18 ║ RI_X      ║
║      19 ║ RX_S      ║
║      20 ║ RX_U      ║
║      21 ║ LAST_MODE ║
╚═════════╩═══════════╝

Die Speicherstruktur, auf die über die DMV zugegriffen wird (mit sqlmin!CMapValuesTable), wird ab der Adresse gespeichert sqlmin!XeSqlPkg::g_lock_mode. Jeder 16-Byte-Eintrag in der Struktur enthält den map_keyund einen Zeiger auf die map_valuevom Streaming-TVF zurückgegebene Zeichenfolge .

Die Zeichenfolgen werden genau wie in der obigen Tabelle gezeigt gespeichert (jedoch nicht in dieser Reihenfolge). Es scheint ein Fehler zu sein, dass Eintrag 21 map_valueanstelle des erwarteten "RX_X" den Wert "LAST_MODE" hat. Erik Darling hat das Problem in Azure Feedback gemeldet .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.