ทำไม RX-X lock นี้ไม่ปรากฏใน Extended Events?


13

ปัญหา

ฉันมีคู่ของคำสั่งที่ทำให้เกิดการล็อค RX-X อย่างไรก็ตามเมื่อฉันใช้ Extended Events เพื่อดูการได้มาของการล็อคการได้รับ RX-X lock ไม่เคยปรากฏขึ้นมันจะออกมาเท่านั้น มันมาจากไหน?

Repro

นี่คือตารางของฉัน:

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

นี่คือชุดปัญหาของฉัน:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN

INSERT dbo.LockTest
VALUES ('bleh')

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

--ROLLBACK

ฉันตรวจสอบล็อคที่ถูกยึดโดยเซสชั่นนี้และดู 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

แต่ฉันยังมีกิจกรรมขยายบนและlock_acquired lock_releasedฉันกรองมันตามความเหมาะสมที่เกี่ยวข้อง _object_id ... ไม่มี RX-X

เอาท์พุทเหตุการณ์เพิ่มเติม

หลังจากดำเนินการย้อนกลับฉันเห็น RX-X (LAST_MODE) เปิดตัวแม้ว่ามันจะไม่ได้รับมาก็ตาม

LAST_MODE

สิ่งที่ฉันได้ลอง

  • ฉันดูล็อคทั้งหมดในเหตุการณ์ที่ขยาย - ไม่มีการกรอง ไม่ได้ล็อค RX-X

  • ฉันลองใช้ Profiler: ผลลัพธ์เดียวกัน (ยกเว้นว่ามันจะได้ชื่อถูกต้อง ... ไม่ใช่ "LAST_MODE")

  • ฉันใช้งาน XE เพื่อเลื่อนระดับล็อค - มันไม่ได้อยู่ที่นั่น

  • ไม่มี XE เฉพาะสำหรับการแปลง แต่ฉันสามารถยืนยันได้ว่าอย่างน้อยที่สุดการแปลง U-X lock ถูกจับโดย lock_acquired

สิ่งที่น่าสังเกตก็คือ RI-N ที่ได้มา แต่ไม่เคยปล่อยออกมา สมมติฐานในปัจจุบันของฉันอยู่ที่ RX-X เป็นล็อคแปลงตามที่อธิบายไว้ที่นี่ มีการล็อคช่วงคีย์ที่ทับซ้อนกันในชุดของฉันที่ดูเหมือนว่าควรมีคุณสมบัติสำหรับการแปลง แต่ล็อค RX-X ไม่ได้อยู่ในตารางการแปลง

ล็อคนี้มาจากไหนและเหตุใดเหตุใดจึงไม่รับเหตุการณ์เพิ่มเติม

คำตอบ:


12

แทรกแถวเดียวได้รับXล็อค (พิเศษ) ในแถวใหม่

SELECTความพยายามในการที่จะได้รับช่วงที่ใช้ร่วมกันที่สำคัญที่ใช้ร่วมกัน ( RangeS-S) ล็อค

คำขอนี้มีรายงานโดยlock_acquiredจัดกิจกรรมขยายโหมด RS_S=

มีการรายงานโดยคลาสเหตุการณ์ Profiler Lock:Acquiredเป็นโหมด 13 ( LCK_M_RS_S)

โหมดการร้องขอจะถูกรวมกับที่มีอยู่แต่เพียงผู้เดียวโหมดล็อคในในLock::CalculateGrantMode sqlmin.dllไม่มีโหมดที่รวมกันของช่วงพิเศษคีย์เอกสิทธิ์ ( RangeS-X) เพื่อให้ผลลัพธ์ของการคำนวณเป็นช่วงพิเศษเอกสิทธิ์คีย์ ( RangeX-X) ซึ่งเกิดขึ้นเป็นโหมด 15

การคำนวณโหมดให้สิทธิ์ข้างต้นจะดำเนินการก่อนที่จะสร้างเหตุการณ์lck_ProduceExtendedEvent<XeSqlPkg::lock_acquired>เพิ่มเติม อย่างไรก็ตามทั้ง Profiler และ Extended Events จะเข้าสู่โหมดที่ร้องขอ RangeS-Sไม่ใช่โหมดล็อคที่RangeX-Xได้ สิ่งนี้ตรงกันข้ามกับเอกสารที่มีข้อ จำกัดซึ่งกล่าวว่า:

โหมด | int | โหมดผลลัพธ์หลังจากล็อคได้มา

โหมดคอลัมน์ของเหตุการณ์ที่ขยายมีเอกสารที่ไม่ทั้งหมดและคำอธิบายในข้อมูลเมตาที่ว่างเปล่า บางที Microsoft เองก็ไม่แน่ใจด้วยซ้ำ

ฉันมักจะคิดว่ามันจะมีประโยชน์มากกว่าถ้าเหตุการณ์ล็อครายงานทั้งโหมดร้องขอและผลลัพธ์แต่นั่นไม่ใช่สิ่งที่เรามี การจัดเรียงในปัจจุบันทำให้เป็นไปไม่ได้ในการติดตามและจับคู่การได้มาและการปลดล็อค

มีอาจจะเป็นเหตุผลที่ดีสำหรับการรายงานล็อคด้วยวิธีนี้ หากไม่ตรงกับความต้องการของคุณคุณสามารถเปิดกรณีการสนับสนุนกับ Microsoft หรือสร้างรายการข้อเสนอแนะ Azure


LAST_MODE

ความลึกลับLAST_MODEเป็นสิ่งที่ Erik Darling ได้กล่าวไว้ก่อนหน้านี้ เป็นmap_keyค่าสูงสุดในรายการโหมดล็อคที่เปิดเผยโดย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 ║
╚═════════╩═══════════╝

โครงสร้างหน่วยความจำเข้าถึงได้ผ่านทาง DMV (ใช้sqlmin!CMapValuesTable) sqlmin!XeSqlPkg::g_lock_modeจะถูกเก็บไว้เริ่มต้นที่อยู่ แต่ละรายการขนาด 16 ไบต์ในโครงสร้างประกอบด้วยmap_keyและตัวชี้ไปยังสตริงที่ส่งคืนmap_valueโดย TVF แบบสตรีม

สตริงจะถูกจัดเก็บไว้อย่างถูกต้องตามที่แสดงในตารางด้านบน (แม้ว่าจะไม่อยู่ในลำดับนั้น) ดูเหมือนว่าจะเป็นข้อผิดพลาดที่รายการ 21 มีmap_valueของ "LAST_MODE" แทนที่จะเป็น "RX_X" ที่คาดไว้ เอริคดาร์ลิ่งได้รายงานปัญหาเกี่ยวกับ Azure ข้อเสนอแนะ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.