Diğer işlemleri engelleyen SPID uyku


16

Yaşadığımız bazı engellemeleri takip etmekte gerçekten zorlanıyorum.

SPID durumunu engelleme kökü, cmd 'COMMAND AWAITING' olduğu 'uyuyan', ve sqltextbir SET TRANSACTION ISOLATION LEVEL READ COMMITTED.

Engellenen İşlem Sayısı ile En İyi İşlem Sayısı raporunu görüntülediğimde, Engellenen SQL İfadesi '-' olur.

Ben SQL üzerinde bir izleme yaptım ve engelleme kök engelleme SPID izleme olduğunda ama gerçekten beni hiçbir yere götürmedi. Son izleme ifadesi sqltextyukarıdakiyle aynıdır SET TRANSACTION ISOLATION LEVEL READ COMMITTED.

TRY / CATCH TREG / COMMIT TRAN / ROLLBACK TRAN ifadelerine sahip olduklarından emin olmak için bulabildiğim tüm ilgili saklı yordamları kontrol ettim (her şey için saklı yordamlar kullanıyoruz, böylece bağımsız ifadeler çalıştırılmıyor). Bu sorun son 24 saat içinde ortaya çıkmaya başladı ve hiç kimse sistemde herhangi bir değişiklik yapmadığını iddia etmiyor.

Çözüm: Nadiren kullanılan saklı prosedürlerimizden birinde bir ekleme ile ilgili bir hata vardı (sütun sayısı eşleşmedi), ancak yine de tam olarak ne olduğu konusunda kafa karıştırıyoruz.

Tüm izleme bilgilerine bakarken, bu saklı yordam için EXEC deyimi zaman zaman listelenmiştir, ancak ASLA BLOCK bloke edici SPID'de gerçekleşmeden hemen önce. Engellemeye başladığında, izlemenin (ya da içindeki ifadelerin herhangi birinin) yürütülmesini kaydetmedi. Bununla birlikte, izlemenin yürütüldüğünü kaydeden başka bir zaman vardı ve hiçbir engelleme olmadı.

Saklı yordam hata raporu bir kullanıcıdan geldi ve ben izlerinde birden fazla EXEC deyimleri bulmak ve SSMS'de çalıştırmak mümkün. Onları çalıştırdığımda hiçbir engelleme olmadı mı yoksa asıldılar mı? Beklendiği gibi koştular (yakalama bloğu, hatadan sonra işlemi tetikledi ve geri aldı). Saklı yordamı düzelttikten sonra sorunu bir daha görmedik.


Engelleme SPID'nin ana bilgisayar adının hiç yardımcı olmadığını varsayıyorum?
Jon Seigel

Hayır, sadece web sunucularımızdan birinin IP'si ... Giriş / kayıt işlemi sırasında (hatanın oluştuğu yer olduğunu düşündüğümüz) her bir SPROC çağrısı için her SQL girişini değiştirmek için başka bir fikrimiz var. hangi SPROC'un engellemeye neden olabileceğini izole etmemize yardımcı olun.
Brad

1
TRY / CATCH derleme hatalarını yakalamayacak ve uyumsuz bir sütun ekleme böyle bir derleme hatası olacaktır. Bu, XX: Tamamlanmış profil oluşturma etkinliklerinin çoğunu da asla tetiklemez.
Remus Rusanu

1
Bu durumda aslında bir derleme hatası değildir, çünkü dahi geliştirici [othertable] 'dan INSERT INTO [table] SELECT * kullandılar ve akranlarına yakalanmadı. SPROC'u Geliştirme üzerine ColdFusion'dan 1000 kez eşzamanlı 3 oturumda çalıştırdım ve asla Üretim'deki gibi bir işlemi açık bırakmadı.
Brad

Yanıtlar:


10

Yorumlardan, SQL sorgusunu iptal eden bir istemci tarafı Komut zaman aşımı olduğunu tahmin ediyorum. Bağlantı SQL Server'da bağlantı havuzu nedeniyle açık kaldığı için bu işlem geri almaz.

Bu nedenle, SET XACT_ABORT ON kullanmanız veya bazı istemci geri alma kodu eklemeniz gerekir

Görmek kanlı ayrıntılar için SQL Server İşlem Zaman Aşımı'na bakın


Tüm SPROC'larımız TL / CATCH blokları ve BEGIN TRAN / COMMIT TRAN / ROLLBACK TRAN ifadelerini içerir, ROLLBACK CATCH'de bulunur. XACT_ABORT'ın hala bir etkisi olur mu?
Brad

@Brad: evet. Bağlantımı görün. Yakalama bloğu CommandTimeout'ta
vurulmuyor

gbn: Teşekkürler. Hala kafam karıştı. Bağlantılarımız hiçbir zaman aşımı olmayacak şekilde ayarlanmıştır (0). Yani bağlantıları yeniden kullanırsak ve bir bağlantı bir hata ile SPROC çalıştırırsa (TL / CATCH ve TRAN blokları vardır), bir şekilde CATCH bloğundaki ROLLBACK'i asla çalıştıramaz, böylece tabloları kilitler ve bir işlem tutar açık? Bu benim için bir anlam ifade etmiyor.
Brad

@Brad: Hatalı bir SPROC, CATCH bloğuna çarpar. Başka türlü ya da farklı demedim. Ancak bağlantım, bir ConnectionTimeout'tan farklı bir CommandTimeout'unuz varsa ne olacağını belirtir. Istemci "iptal" diyor ve SQL Server işlemeyi durdurur. Ergo, CATCH bloğu veya geri
dönüşü

Belirtilen bir CommandTimeout'umuz olduğunu sanmıyorum. Depolanan tüm prosedürlerimiz sqlstress kullanılarak test edilmektedir ve 10 kullanıcıda 10 ms'den az (en az) tekrar etmelidir. Neler olduğu konusunda hala çok kafam karıştı, ancak soruyu sorunun ne olduğunu bulduğumuzla güncelliyorum.
Brad

9

Yürütülen son ifadeyi görmek için sys.dm_exec_connections içindeki most_recent_sql_handle öğesini kullanın.

SELECT  t.text,
        QUOTENAME(OBJECT_SCHEMA_NAME(t.objectid, t.dbid)) + '.'
        + QUOTENAME(OBJECT_NAME(t.objectid, t.dbid)) proc_name,
        c.connect_time,
        s.last_request_start_time,
        s.last_request_end_time,
        s.status
FROM    sys.dm_exec_connections c
JOIN    sys.dm_exec_sessions s
        ON c.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t
WHERE   c.session_id = 72;--your blocking spid

Ayrıca bu örümcek için açık bir işlem olup olmadığını kontrol edin

SELECT  st.transaction_id,
        at.name,
        at.transaction_begin_time,
        at.transaction_state,
        at.transaction_status
FROM    sys.dm_tran_session_transactions st
JOIN    sys.dm_tran_active_transactions at
        ON st.transaction_id = at.transaction_id
WHERE   st.session_id = 72;--your blocking spid

En DBCC INPUTBUFFER(spid)son yürütülen SQL'i görmek için de kullanabilirsiniz .
Mike Fal

Tüm bunları kullandım ve son komut her zaman orijinal yazıma koyduğum şeydi: SET TRANSACTION ISOLATION LEVEL READ COMMITTED. Ben de DBCC OPENTRAN koştu ve engelleme PID için açık bir işlem olduğunu görebilirsiniz.
Brad

İfade gerçekten bir prosedürün parçasıysa, ilk seçimim size prosedür adını verir.
Sebastian Meine

Web sunucularımızdan hiçbir adhoc sorgusu kullanmamanızı sağlarım ve bu ilk sorguyu çalıştırdığımda, WHERE yan tümcesi olmadan bile, sadece bir avuç SQL oturumunda SPROC'u alıyorum, geri kalan sütun NULL.
Brad

'İŞLEM İZOLASYON DÜZEYİNİ OKUYUN DEVAM EDİLDİ' diyen tonlarca oturumum olduğunu ve hepsinin ColdFusion'dan (web sunucularımızda kullanılan ana komut dosyası) olduğunu fark ettim. Belki de boşta olduğunda, açık bir bağlantıyı açık tutmak için (bağlantıları açık tutmaya ayarlandığı için) ColdFusion.
Brad

4

Adam Machanic'in sp_whoisactive'i kullanmayı denediniz mi? Dış komutun gerçekten bir proc içinde olup olmadığını görmek için bir seçenek var. Uygulama işlem yapmak yerine bir işlemi açık tutuyor olabilir. DBCC OPENTRAN'a da bakmayı deneyin .


DBCC OPENTRAN için teşekkürler. Engelleme PID'sinin açık bir işlemi olduğunu, ancak daha fazla ayrıntı bulunmadığını söylüyor. sp_whoisactive engellenen işlemle aynı bilgiyi kendi başıma alabildiğim gibi döndürür. 'İŞLEM İZOLASYON DÜZEYİNİ OKUYUN DEVAM EDİLDİ' dışında neler olup bittiği hakkında henüz bir ayrıntı yok
Brad
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.