Cara melacak pemblokiran yang terjadi kurang dari sedetik - SQL Server

14

Saya mencoba memecahkan masalah pemblokiran yang terjadi kurang dari sedetik. Aplikasi OLTP sangat sensitif dan harus memiliki waktu respons kurang dari 200 ms untuk beberapa transaksi sesuai SLA yang disepakati. Kami memiliki beberapa masalah eskalasi kunci dengan rilis kode baru yang dapat kami atasi dengan mengurangi ukuran batch dalam pembaruan. Bahkan dengan ukuran batch yang kecil, kami menduga bahwa sp baru memblokir baris yang sama dengan yang diperbarui oleh transaksi OLTP.

Saya perlu menemukan sesi yang diblokir dan sumber dayanya menunggu. Sesuai pemahaman saya, "ambang proses yang diblokir" dapat disetel minimal 1 detik sehingga tidak akan menangkap pemblokiran.

Saya bereksperimen dengan wait_info dan wait_completed x events.

Apakah ada cara lain untuk melacak ini? Terima kasih

jesijesi
sumber
pertanyaan yang sama tentang itu oleh pengguna yang sama: stackoverflow.com/questions/38407021/…
TheGameiswar

Jawaban:

10

Karena Anda secara khusus tertarik untuk mengunci daripada menunggu secara umum, locks_lock_waitsacara yang diperpanjang terdengar lebih cocok.

Dengan filter aktif increment >= 200

CREATE EVENT SESSION [locks_lock_waits] ON SERVER 
ADD EVENT sqlserver.locks_lock_waits(
        ACTION(sqlserver.sql_text)
            WHERE  ( [sqlserver].[is_system] = 0
                     AND [increment] >= 200
                     AND [counter] <= 1000 ) 
    )
ADD TARGET package0.ring_buffer;

GO

ALTER EVENT SESSION [locks_lock_waits]  
ON SERVER  STATE = start;  

Di atas mengumpulkan pernyataan menunggu kunci untuk jumlah ambang waktu tetapi tidak memberikan sumber daya kunci spesifik.

Saya belum pernah menggunakan acara ini dan tidak memiliki wawasan tentang berapa banyak overhead sesi ini akan menyebabkan pada server produksi Anda.

Saya menemukan video ini pada topik. Itu sangat merekomendasikan penyaringan counteruntuk mengurangi jumlah acara yang dikumpulkan dan saya telah melakukannya di atas.

Itu juga menyebutkan perintah lama yang tidak terdokumentasi

dbcc lock(StallReportThreshold, 200) -- 200 is threshold in ms

Yang (jika jejak bendera 3605 diaktifkan) membuang informasi terbatas seperti di bawah ini ke log galat SQL Server.

Proses 53 menunggu 6844 ms untuk kunci S pada RID: 2: 1: 120: 2 hasil: OKWAIT

Saya hanya menyebutkan ini secara sepintas karena acara yang diperluas jelas akan lebih disukai karena didokumentasikan dan jauh lebih kuat.

Martin Smith
sumber
Saya menguji locks_lock_waits, dan seperti yang Anda katakan tidak memiliki info sumber daya. Tetapi saya tidak tahu bahwa kenaikan adalah waktu. Info bagus kunci dbcc, tampak hebat. Apakah Anda tahu berapa lama informasi itu tersedia sebelum dapat dibuang ke log kesalahan.
jesijesi
Maaf, saya tidak membuat diri saya jelas. Saya bertanya, berapa lama kita sampai kita menjalankan perintah kunci dbcc. Misalnya penguncian terjadi dan jika saya menjalankan kunci dbcc setelah satu jam, apakah kami masih mendapatkan info?
jesijesi
@ jesijesi - Saya belum pernah mendengarnya sebelumnya hari ini. Saya tidak punya informasi lebih lanjut tentang itu. Saya bahkan tidak tahu parameter yang harus dilewati untuk menonaktifkannya. Tetapi Anda menjalankan dbcc lock(StallReportThreshold, 200) pertama dan itu mengeluarkan info setelah ambang melebihi selama jejak bendera 3605 diaktifkan. SQL Server tidak mengumpulkan info ini kalau-kalau Anda mungkin menjalankannya nanti.
Martin Smith
2
Terima kasih. cukup menambahkan tautan yang memiliki fungsi berguna untuk mengonversi nilai resource_0,1,2 dalam xevents. sqlnotes.info/2011/10/24/…
jesijesi
5

Jika Anda tertarik untuk mengunci, ada beberapa acara tambahan yang tersedia:

lock_acquired
lock_released
lock_escalation

Dua peristiwa pertama memiliki durationkolom dalam (mikrodetik) yang dapat Anda filter untuk ambang Anda. Mereka juga memiliki resource_descriptiontindakan yang akan memberi Anda detail tentang sumber daya yang terlibat.

The lock_escalationevent juga memiliki statementtindakan yang dapat Anda tambahkan untuk mengumpulkan pernyataan T-SQL yang memicu eskalasi kunci. Itu juga punya escalation_cause. Inilah sesi sampel:

CREATE EVENT SESSION [locking] ON SERVER 
ADD EVENT sqlserver.lock_acquired( SET collect_resource_description = (1) ),
ADD EVENT sqlserver.lock_escalation( SET collect_statement = (1) ),
ADD EVENT sqlserver.lock_released( SET collect_resource_description = (1) )
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO

Saya menduga mungkin ada alasan Anda tidak dapat mengatur ambang laporan proses yang diblokir menjadi kurang dari satu detik: penguncian adalah sangat normal di RDBMS - mesin basis data harus mengunci sumber daya untuk melindungi mereka. Meskipun tidak ada definisi resmi tentang kapan penguncian menjadi memblokir, penguncian berdetak di atas detik, sepertinya agak normal bagi saya.

wBob
sumber
1
penguncian menjadi memblokir segera setelah orang lain ditolak akses ke sumber daya dan harus menunggu karena kunci.
Martin Smith
Terima kasih, saya berencana menggunakan lock_acquired dengan bidang durasi.
jesijesi
Semoga berhasil. Saat Anda menggunakan SQL Server 2014, Anda bisa menggunakan tabel OLTP dalam memori dengan procs tersimpan yang disusun secara asli menawarkan opsi bebas-latch kinerja tinggi. Anda juga bisa melihat isolasi snapshot.
wBob