Sch-M WAIT บล็อก Sch-S ใน SQL Server 2014 แต่ไม่ใช่ SQL Server 2008 R2?


11

เราเพิ่งโอนย้ายอินสแตนซ์การผลิตของเราจาก SQL 2008 R2 ไปเป็นเซิร์ฟเวอร์ SQL 2014 ใหม่ล่าสุด นี่เป็นสถานการณ์ที่น่าสนใจที่เราค้นพบกับการใช้บริการของเรา พิจารณาฐานข้อมูลที่มีBroker Enabled = trueด้วยและMyService MyQueueการจัดการข้อความพิษถูกปิดใช้งานในคิวนี้ มีการสนทนาอย่างน้อย 2 ครั้งที่มีข้อความในคิว

ในหนึ่งกระบวนการ (SPID 100) ดำเนินการ:

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

โปรดทราบว่าเราปล่อยให้ธุรกรรมเปิดอยู่ ลองนึกภาพว่ามันเป็นโปรแกรม. NET ที่กำลังรอทรัพยากรภายนอกอยู่นาน ผ่านทางsys.dm_tran_locksเราเห็นว่า SPID นี้ได้รับการล็อคทรงเครื่องบนคิว

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

ในกระบวนการที่แยกต่างหาก (SPID 101) ดำเนินการห้าครั้ง :

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

ที่สำคัญนี่คือการที่เราจะกลิ้งกลับการทำธุรกรรมครั้งที่ห้า สิ่งนี้ทริกเกอร์ตรรกะพื้นหลังการจัดการข้อความพิษที่สร้างขึ้น ในขณะที่คิวไม่ได้ถูกปิดใช้งาน (เนื่องจากถูกกำหนดค่าเป็นไม่ปิดใช้งาน) งานพื้นหลังยังคงพยายามทำงานและเริ่มต้นbroker_queue_disabledเหตุการณ์ ดังนั้นตอนนี้ถ้าเราสอบถามsys.dm_tran_locksอีกครั้งเราจะเห็น SPID อื่น (เกี่ยวข้องกับBRKR TASK) รอการล็อคแบบ Sch-M

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

จนถึงตอนนี้ทุกอย่างเข้าท่า

ในขั้นตอนอื่น (SPID 102) ให้ลองส่งบริการโดยใช้คิวนั้น:

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

SENDคำสั่งจะถูกปิดกั้น ถ้าเราดูอีกครั้งsys.dm_tran_locksเราจะเห็นว่ากระบวนการนี้กำลังรอการล็อค Sch-S การดำเนินการsp_who2เราพบว่า SPID 102 ถูกปิดกั้นโดย 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  |

เหตุใดการล็อค Sch-S จึงรอการล็อค Sch-M ที่รออยู่ด้วย

พฤติกรรมนี้แตกต่างอย่างสิ้นเชิงใน SQL 2008 R2! การใช้สถานการณ์เดียวกันนี้โดยทำงานในอินสแตนซ์ 2008R2 ที่ยังไม่เป็นที่เรียบร้อยของเราแบทช์สุดท้ายรวมถึงSENDคำสั่งจะไม่ถูกบล็อกโดยล็อค Sch-M ที่รออยู่

พฤติกรรมการล็อคเปลี่ยนไปใน SQL 2012 หรือ 2014 หรือไม่ อาจมีการตั้งค่าฐานข้อมูลหรือเซิร์ฟเวอร์บางอย่างซึ่งอาจมีผลต่อพฤติกรรมการล็อคนี้หรือไม่?


ฟังดูเหมือนเป็นข้อผิดพลาดที่เป็นไปได้ คุณใช้ SP และ CU ล่าสุดหรือไม่
Max Vernon

1
@ MaxVernon เรากำลังทำงาน 12.00.2370
Joseph Daigle

3
คุณใช้บริการเดียวกับผู้ริเริ่มและกำหนดเป้าหมาย SENDบล็อกขณะที่การตรวจสอบริเริ่มคิว SENDจะไม่ปิดกั้นคิวเป้าหมายมันจะเด้งและใช้sys.transmission_queueสำหรับการจัดส่ง หากคุณแยกทั้งสอง (เป็นความคิดที่ดีเสมอ) คุณจะไม่มีปัญหา
Remus Rusanu

1
ขอบคุณ @RemusRusanu ในขณะที่ตัวอย่างนี้มีบางส่วนที่แสดงให้เห็นถึงพฤติกรรมที่เปลี่ยนแปลง แต่เคล็ดลับของคุณคือสิ่งที่เราควรทราบเมื่อเราออกแบบบริการและคิวของเรา
โจเซฟไดเกิล

คำตอบ:


17

พฤติกรรมนั้นเปลี่ยนไประหว่าง SQL Server 2008 R2 และ SQL Server 2012 การใช้งาน 2008 R2 นั้นไม่สอดคล้องกับความหมายของเอกสาร 'ผ่อนคลาย FIFO' :

ล็อคจะได้รับในแฟชั่นเข้าก่อนออกก่อน (FIFO) ที่ผ่อนคลาย แม้ว่าคำสั่งจะไม่เข้มงวด FIFO แต่ก็รักษาคุณสมบัติที่ต้องการเช่นการหลีกเลี่ยงความอดอยากและการทำงานเพื่อลดการหยุดชะงักที่ไม่จำเป็นและการปิดกั้น

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

คำขอแปลงจะถูกบล็อกก็ต่อเมื่อโหมดที่ร้องขอนั้นเข้ากันไม่ได้กับการรวมกันของโหมดที่ได้รับอนุญาตทั้งหมดยกเว้นโหมดที่มีการร้องขอการแปลงด้วยตนเองในตอนแรก

ในปี 2008 R2 Sch-Sคำขอการล็อคใหม่ได้รับแม้ว่าจะไม่เข้ากันกับการรวมคำขอที่ได้รับและการรอซึ่งอาจนำไปสู่การอดอาหาร ในปี 2012 Sch-Sคำขอล็อคถูกบล็อค

สคริปต์การทำซ้ำด้านล่างใช้ตารางปกติมากกว่าคิวบริการนายหน้า

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

โดยสรุป 2008 R2 ไม่ทำงานตามที่ออกแบบไว้ ปัญหาได้รับการแก้ไขใน SQL Server 2012

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