Sch-M WAIT memblokir Sch-S di SQL Server 2014 tetapi tidak SQL Server 2008 R2?

11

Kami baru-baru ini memigrasi instance produksi kami dari SQL 2008 R2 ke server SQL 2014 baru. Berikut adalah skenario menarik yang kami temukan dengan penggunaan Broker Layanan kami. Pertimbangkan basis data Broker Enabled = truedengan MyServicedan MyQueue. Penanganan pesan racun dinonaktifkan pada antrian ini. Setidaknya ada 2 percakapan aktif dengan pesan dalam antrian.

Dalam satu proses (SPID 100) jalankan:

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

Perhatikan bahwa kami membiarkan transaksi terbuka. Bayangkan itu adalah program .NET yang menunggu lama pada beberapa sumber daya eksternal. Melalui sys.dm_tran_lockskita melihat bahwa SPID ini telah diberikan kunci IX pada antrian.

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

Dalam proses terpisah (SPID 101) jalankan lima kali :

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

Kuncinya di sini adalah bahwa kita memutar kembali transaksi lima kali . Ini memicu logika latar belakang Penanganan Pesan Racun bawaan . Sementara antrian tidak dinonaktifkan (karena dikonfigurasi untuk tidak menonaktifkan), tugas latar belakang masih mencoba melakukan pekerjaan dan menjalankan suatu broker_queue_disabledacara. Jadi sekarang jika kita query sys.dm_tran_lockslagi kita akan melihat SPID berbeda (terkait dengan BRKR TASK) menunggu kunci Sch-M.

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

Sejauh ini, semuanya masuk akal.

Akhirnya, pada proses yang berbeda (SPID 102), cobalah untuk MENGIRIM ke Layanan menggunakan Antrian itu:

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

The SENDperintah diblokir. Jika kita melihat lagi pada sys.dm_tran_lockskita melihat bahwa proses ini menunggu pada kunci Sch-S. Melaksanakan sp_who2kami menemukan bahwa SPID 102 diblokir oleh 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  |

Mengapa kunci Sch-S menunggu pada kunci Sch-M yang juga menunggu?

Perilaku ini sangat berbeda dalam SQL 2008 R2! Menggunakan skenario yang sama persis ini, berjalan pada contoh 2008R2 kami yang belum dinonaktifkan, batch terakhir termasuk SENDperintah tidak akan diblokir oleh kunci Sch-M yang menunggu.

Apakah perilaku penguncian berubah di SQL 2012 atau 2014? Apakah mungkin ada beberapa pengaturan database atau server yang dapat mempengaruhi perilaku penguncian ini?

Joseph Daigle
sumber
Kedengarannya seperti bug yang mungkin. Sudahkah Anda menerapkan SP dan CU terbaru?
Max Vernon
1
@ MaxVernon kita menjalankan 12.00.2370
Joseph Daigle
3
Anda menggunakan layanan yang sama dengan inisiator dan target. The SENDblok sambil memeriksa inisiator antrian. SENDtidak akan memblokir antrian target , itu hanya akan terpental dan digunakan sys.transmission_queueuntuk pengiriman. Jika Anda memisahkan keduanya (selalu merupakan ide bagus), Anda tidak akan memiliki masalah.
Remus Rusanu
1
Terima kasih @RemusRusanu. Meskipun contoh ini dibuat sebagian untuk menunjukkan perilaku yang berubah, tip Anda adalah tip yang akan kami ingat ketika kami merancang layanan dan antrian kami.
Joseph Daigle

Jawaban:

17

Perilaku memang berubah antara SQL Server 2008 R2 dan SQL Server 2012. Implementasi 2008 R2 tidak konsisten dengan semantik 'santai FIFO' yang didokumentasikan :

Kunci diberikan dengan cara masuk pertama, keluar pertama (FIFO) yang santai. Meskipun urutannya bukan FIFO yang ketat, ia mempertahankan sifat-sifat yang diinginkan seperti menghindari kelaparan dan bekerja untuk mengurangi kebuntuan dan pemblokiran yang tidak perlu.

Permintaan kunci baru di mana pemohon belum memiliki kunci pada sumber daya menjadi diblokir jika mode yang diminta tidak sesuai dengan penyatuan permintaan yang diberikan dan mode permintaan yang tertunda.

Permintaan konversi menjadi diblokir hanya jika mode yang diminta tidak sesuai dengan penyatuan semua mode yang diberikan, tidak termasuk mode di mana permintaan konversi itu sendiri awalnya diberikan.

Pada 2008 R2, Sch-Spermintaan kunci baru dikabulkan meskipun tidak sesuai dengan penyatuan permintaan yang dikabulkan dan menunggu, yang dapat menyebabkan kelaparan kunci. Pada 2012, Sch-Spermintaan kunci diblokir.

Skrip reproduksi di bawah ini menggunakan tabel biasa daripada antrian Pialang Layanan:

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

Singkatnya, 2008 R2 tidak berperilaku seperti yang dirancang. Masalahnya diperbaiki pada SQL Server 2012.

Paul White 9
sumber