Sch-M WAIT chặn Sch-S trong SQL Server 2014 nhưng không phải SQL Server 2008 R2?


11

Gần đây chúng tôi đã di chuyển các phiên bản sản xuất của chúng tôi từ SQL 2008 R2 sang các máy chủ SQL 2014 hoàn toàn mới. Đây là một kịch bản thú vị mà chúng tôi đã phát hiện ra khi sử dụng Nhà môi giới dịch vụ. Hãy xem xét một cơ sở dữ liệu Broker Enabled = truevới MyServiceMyQueue. Xử lý tin nhắn độc bị vô hiệu hóa trên hàng đợi này. Có ít nhất 2 cuộc hội thoại hoạt động với các tin nhắn trong hàng đợi.

Trong một quy trình (SPID 100) thực thi:

BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;

Lưu ý rằng chúng tôi để giao dịch mở. Hãy tưởng tượng rằng đó là một chương trình .NET đang chờ một thời gian dài trên một số tài nguyên bên ngoài. Qua sys.dm_tran_lockschúng tôi thấy rằng SPID này đã được cấp khóa IX trên hàng đợi.

| type   | resource_id | mode | status | spid |
| OBJECT | 277576027   | IX   | GRANT  | 100  |

Trong một quy trình riêng biệt (SPID 101) thực hiện năm lần :

BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
ROLLBACK TRANSACTION;

Chìa khóa ở đây là chúng tôi đang quay lại giao dịch năm lần . Điều này kích hoạt logic nền xử lý thông điệp Poison tích hợp. Mặc dù hàng đợi không bị vô hiệu hóa (vì nó được cấu hình để không vô hiệu hóa), một tác vụ nền vẫn đang cố gắng thực hiện công việc và thực hiện một broker_queue_disabledsự kiện. Vì vậy, bây giờ nếu chúng ta truy vấn sys.dm_tran_lockslại, chúng ta sẽ thấy một SPID khác (được liên kết với BRKR TASK) đang chờ trên khóa Sch-M.

| type   | resource_id | mode  | status | spid |
| OBJECT | 277576027   | IX    | GRANT  | 100  |
| OBJECT | 277576027   | Sch-M | WAIT   | 36   |

Cho đến nay, mọi thứ đều có ý nghĩa.

Cuối cùng, trên một quy trình khác (SPID 102), hãy thử GỬI đến một Dịch vụ bằng cách sử dụng Hàng đợi đó:

BEGIN TRANSACTION;
DECLARE @ch uniqueidentifier;
BEGIN DIALOG @ch FROM SERVICE [MyService] TO SERVICE 'MyService';
SEND ON CONVERSATION @ch ('HELLO WORLD');

Các SENDlệnh được chặn. Nếu chúng ta nhìn lại sys.dm_tran_lockschúng ta sẽ thấy rằng quá trình này đang chờ khóa Sch-S. Thực hiện sp_who2chúng tôi thấy rằng SPID 102 bị chặn bởi SPID 36.

| type   | resource_id | mode  | status | spid |
| OBJECT | 277576027   | IX    | GRANT  | 100  |
| OBJECT | 277576027   | Sch-M | WAIT   | 36   |
| OBJECT | 277576027   | Sch-S | WAIT   | 102  |

Tại sao khóa Sch-S lại đợi trên khóa Sch-M cũng đang chờ?

Hành vi này là hoàn toàn khác nhau trong SQL 2008 R2! Sử dụng chính xác kịch bản này, chạy trên các phiên bản 2008R2 sắp ngừng hoạt động của chúng tôi, lô cuối cùng bao gồm SENDlệnh không bị chặn bởi khóa Sch-M đang chờ.

Hành vi khóa đã thay đổi trong SQL 2012 hoặc 2014? Có lẽ có một số cơ sở dữ liệu hoặc cài đặt máy chủ có thể ảnh hưởng đến hành vi khóa này?


Âm thanh như một lỗi có thể. Bạn đã áp dụng SP và CU mới nhất chưa?
Max Vernon

1
@MaxVernon chúng tôi đang chạy 12.00.2370
Joseph Daigle

3
Bạn đang sử dụng dịch vụ giống như người khởi xướng và mục tiêu. Các SENDkhối trong khi kiểm tra hàng đợi khởi tạo . SENDsẽ không chặn trên hàng đợi đích , nó chỉ đơn giản là bị trả lại và sử dụng sys.transmission_queueđể phân phối. Nếu bạn tách hai người (luôn luôn là một ý tưởng tốt), bạn sẽ không gặp vấn đề gì.
Remus Rusanu

1
Cảm ơn @RemusRusanu. Mặc dù ví dụ này được dự định một phần để chứng minh hành vi đã thay đổi, mẹo của bạn là chúng tôi sẽ ghi nhớ khi chúng tôi thiết kế các dịch vụ và hàng đợi của chúng tôi.
Joseph Daigle

Câu trả lời:


17

Hành vi đã thay đổi giữa SQL Server 2008 R2 và SQL Server 2012. Việc triển khai 2008 R2 không phù hợp với ngữ nghĩa 'thư giãn của FIFO' :

Khóa được cấp theo kiểu thoải mái vào trước, ra trước (FIFO). Mặc dù trật tự không nghiêm ngặt theo kiểu FIFO, nhưng nó vẫn giữ được các đặc tính mong muốn như tránh chết đói và hoạt động để giảm các bế tắc và chặn không cần thiết.

Các yêu cầu khóa mới mà người yêu cầu chưa sở hữu khóa trên tài nguyên sẽ bị chặn nếu chế độ được yêu cầu không tương thích với sự kết hợp của các yêu cầu được cấp và các chế độ của yêu cầu đang chờ xử lý.

Yêu cầu chuyển đổi chỉ bị chặn nếu chế độ được yêu cầu không tương thích với sự kết hợp của tất cả các chế độ được cấp, ngoại trừ chế độ mà chính yêu cầu chuyển đổi ban đầu được cấp.

Trong năm 2008 R2, một Sch-Syêu cầu khóa mới đã được cấp mặc dù nó không tương thích với sự kết hợp của các yêu cầu được cấp và chờ, điều này có thể dẫn đến tình trạng chết đói. Trong năm 2012, Sch-Syêu cầu khóa bị chặn.

Tập lệnh sao chép bên dưới sử dụng các bảng thông thường thay vì hàng đợi Nhà môi giới dịch vụ:

-- Session 1
CREATE TABLE dbo.LockTest (col1 integer NULL);

INSERT dbo.LockTest (col1) VALUES (1);

BEGIN TRANSACTION;

-- Will hold row-X, Pag-IX, and Tab-IX
INSERT dbo.LockTest (col1) VALUES (2);

-- Session 2
-- Blocked waiting on Sch-M
TRUNCATE TABLE dbo.LockTest;

-- Session 3
-- Takes Sch-S only
-- Not blocked in 2008 R2
SELECT * FROM dbo.LockTest AS LT WITH (READUNCOMMITTED);

Tóm lại, 2008 R2 không hoạt động như thiết kế. Sự cố đã được khắc phục trong SQL Server 2012.

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.