Tại sao khóa RX-X này không xuất hiện trong Sự kiện mở rộng?


13

Vấn đề

Tôi có một cặp truy vấn, dưới sự cô lập tuần tự hóa, gây ra khóa RX-X. Tuy nhiên, khi tôi sử dụng Sự kiện mở rộng để xem việc mua lại khóa, việc mua lại khóa RX-X không bao giờ xuất hiện, nó chỉ được phát hành. Nó đến từ đâu?

Repro

Đây là bảng của tôi:

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

Đây là lô vấn đề của tôi:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN

INSERT dbo.LockTest
VALUES ('bleh')

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

--ROLLBACK

Tôi kiểm tra các khóa được giữ bởi phiên này và xem 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

Nhưng tôi cũng có một sự kiện mở rộng trên lock_acquiredlock_released. Tôi lọc nó trên Associ_object_id thích hợp ... không có RX-X.

Đầu ra sự kiện mở rộng

Sau khi thực hiện rollback, tôi thấy RX-X (LAST_MODE) được phát hành, mặc dù nó không bao giờ được mua lại.

LAST_MODE

Những gì tôi đã thử

  • Tôi đã xem xét tất cả các khóa trong Sự kiện mở rộng - không lọc. Không có khóa RX-X có được.

  • Tôi cũng đã thử Profiler: kết quả tương tự (tất nhiên ngoại trừ nó có tên đúng ... không "LAST_MODE").

  • Tôi đã chạy XE để leo thang khóa - nó không có ở đó.

  • Không có XE dành riêng cho chuyển đổi, nhưng tôi có thể xác nhận rằng ít nhất chuyển đổi khóa U thành X được nắm bắt bởi lock_acquired

Cũng cần lưu ý là RI-N được mua nhưng không bao giờ được phát hành. Giả thuyết hiện tại của tôi là RX-X là một khóa chuyển đổi, như được mô tả ở đây . Có các khóa phạm vi khóa chồng chéo trong lô của tôi trông giống như chúng đủ điều kiện để chuyển đổi, nhưng khóa RX-X không có trong bảng chuyển đổi.

Khóa này đến từ đâu và tại sao nó không được chọn bởi Sự kiện mở rộng?

Câu trả lời:


12

Hàng đơn chèn có Xkhóa (độc quyền) trên hàng mới.

Các SELECTnỗ lực để có được khóa chia sẻ phạm vi, khóa được chia sẻ ( RangeS-S).

Yêu cầu này được báo cáo bởi lock_acquiredSự kiện mở rộng dưới dạng mode = RS_S.

Nó được báo cáo bởi lớp sự kiện Profiler Lock:Acquiredlà chế độ 13 ( LCK_M_RS_S).

Phương thức yêu cầu được kết hợp với hiện độc quyền chế độ khóa ở Lock::CalculateGrantModetrong sqlmin.dll. Không có chế độ kết hợp của chia sẻ phạm vi, độc quyền khóa ( RangeS-X) vì vậy kết quả của phép tính là độc quyền phạm vi, độc quyền khóa ( RangeX-X), xảy ra ở chế độ 15.

Tính toán chế độ cấp ở trên được thực hiện ngay trước khi sự kiện mở rộng được tạo bởi lck_ProduceExtendedEvent<XeSqlPkg::lock_acquired>. Tuy nhiên, cả Profiler và Extended Events đều ghi lại chế độ được yêu cầu RangeS-S , không phải chế độ khóa kết quả RangeX-X. Điều này trái với tài liệu giới hạn , trong đó nói:

Chế độ | int | Chế độ kết quả sau khi khóa được mua.

Các chế độ cột của sự kiện kéo dài không có giấy tờ gì cả, và mô tả trong các dữ liệu meta là trống. Có lẽ chính Microsoft thậm chí không chắc chắn về hành vi.

Tôi thường nghĩ sẽ hữu ích hơn nếu các sự kiện khóa báo cáo cả chế độ được yêu cầukết quả , nhưng đó không phải là những gì chúng ta có. Sự sắp xếp hiện tại làm cho nó khá nhiều không thể theo dõi và phù hợp với việc mua và phát hành khóa.

thể có một lý do tốt để báo cáo khóa theo cách này. Nếu nó không đáp ứng nhu cầu của bạn, bạn có thể mở trường hợp hỗ trợ với Microsoft hoặc tạo một mục Phản hồi Azure.


LAST_MODE

Bí ẩn LAST_MODElà điều mà Erik Darling đã nhận xét trước đó . Đây là map_keygiá trị cao nhất trong danh sách các chế độ khóa được hiển thị bởi 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 ║
╚═════════╩═══════════╝

Cấu trúc bộ nhớ được truy cập thông qua DMV (sử dụng sqlmin!CMapValuesTable) được lưu trữ bắt đầu tại địa chỉ sqlmin!XeSqlPkg::g_lock_mode. Mỗi mục 16 byte trong cấu trúc chứa map_keyvà một con trỏ tới chuỗi được trả về như map_valueTVF truyền phát.

Các chuỗi được lưu trữ chính xác như được hiển thị trong bảng trên (mặc dù không theo thứ tự đó). Có vẻ như là một lỗi mà mục 21 có map_value"LAST_MODE" thay vì "RX_X" dự kiến. Erik Darling đã báo cáo vấn đề trên Azure Feedback .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.