Artan ağ gecikmesi MS SQL Server'da tablo kilitlerine neden olur mu?


16

Yüksek gecikmeli bir ağ üzerinden SQL Server veritabanına tek bir çağrı yapıyorsam, bu gecikmeler nedeniyle tablo kilitleri oluşacak mı? Diyelim ki bazı kayıtlar için tablo A'yı sorguladım ve SQL Server bu verileri yavaş bir ağ üzerinden döndürmek zorunda - sunucu A'dan yanıt gönderirken ağ üzerinden bir okuma kilidi olacak mı yoksa SQL Server göndermeden önce kilidi serbest bırakacak mı? cevap?

Ayrıca, yanıt, yanıtın boyutuna bağlı olarak değişebilir mi? Birkaç KB'ye yüzlerce MB'ye dönmek zorundaysa, bu bir fark yaratır mı?

Açık bir işlem oluşturmak, sorgular çalıştırmak ve işlemi kapatmak, işlemin gecikme süresiyle ilişkili olduğundan tabloların kilitlenmesine neden olur.


Bir nolockipucu belirtmedikçe , her zaman bir kilit olacaktır . Gecikme, kilidin ne kadar süreyle tutulacağını belirler.
Brandon


@brandon Microsoft tarafından herhangi bir yerde belgeleniyor mu? Aramalarım boş çıktı.
Evan M

1
@Brandon NOLOCK, ne demek istediğinizi kastetmez.
Aaron Bertrand

3
@Brandon Unless you specify a nolock hint, there will always be a lock.<- Eğer nolock kullanırsanız kilit olmayabilir. Sadece açıklığa kavuştum.
Aaron Bertrand

Yanıtlar:


15

İstemcinin veri alması ve SQL Server'a veri aldığını bildirmesi uzun zaman alırsa, SQL Server'ın beklemesi gereken bu beklemeden dolayı SQL Server, istemciden onay alınmadıkça sorgu tarafından tutulan kilitleri serbest bırakmaz.

Bu doğru değil, izolasyon seviyesine bağlıdır.

Varsayılan olarak READ COMMITTEDkilitler ifadelerin yürütülmesi süresince tutulmaz. READ COMMITTEDdeyim düzeyinde okuma tutarlılığı sağlamaz, tek garanti, taahhüt edilmemiş verileri okuyamayacağınızdır. Paylaşılan bir kilit alınır ve satırı okumak için tutulur ve serbest bırakılır.

LOB tipiniz olmadığı sürece.

Potansiyel olarak çok büyük olan LOB tipleri tamponlanamaz. Paylaşılan kilit size esas veren deyim tamamlanıncaya kadar kazanılmış ve tutulmalıdır REPEATABLE READde davranış READ COMMITTED.

Yüksek gecikmeli bir ağ üzerinden MSSQL veritabanına tek bir çağrı yapıyorsam, bu gecikmeler nedeniyle tablo kilitleri oluşacak mı?

Gecikme, masa kilidine neden olmaz, hayır. Ancak, bir masa kilidi edinilmişse, gecikme süresi uzatacaktır.

Bunun mekaniğini benden daha iyi bilen birini alıntılamak için ( @RemusRusanu ):

Yürütme devam ettikçe sonuçlar istemci programına geri döndürülür. Satırlar yürütme ağacını 'kabarcıkladığında', en iyi işleç genellikle bu satırları ağ arabelleklerine yazmak ve istemciye geri göndermekle görevlendirilir. Sonuç ilk önce bazı ara depolarda (bellek veya disk) oluşturulmaz ve daha sonra istemciye geri gönderilir, bunun yerine oluşturulduğu gibi geri gönderilir (sorgu yürütüldüğünde). Sonucu istemciye geri göndermek elbette ağ akış kontrol protokolüne tabidir. İstemci sonucu aktif olarak tüketmiyorsa (örneğin, SqlDataReader.Read () öğesini çağırarak), sonunda akış kontrolünün gönderen tarafı (yürütmekte olan sorgu) engellemesi gerekecektir ve bu da uygulamanın yürütülmesini askıya alacaktır. sorgu.[kaynak]

Sonuçlar, istemci veya ağ nedeniyle SQL Server'ın sunabildiği kadar hızlı tüketilmediğinde, ASYNC_NETWORK_IObiriken beklemeleri görüyoruz . Tekrarlamak gerekirse, bu, elde edilen kilitleri değil, sadece tutuldukları süreyi etkilemez.


9

Mark'ın cevabı karışıklığımın çoğunu temizledi, ancak gecikmeyi taklit etmek için NetBalancer kullanarak test ettikten sonra bulgularımı göndermek istedim.

Yerel makinemi uzak bir SQL sunucusunu çağırdım ve hem SELECT'leri hem de INSERT'leri küçük bir işlem içinde bir tablo üzerinde yürüttüm. Uzak makinede, yerel SQL örneğine bağlandım ve sys.dm_tran_locks tablosu üzerinde tekrar tekrar yinelemek ve değiştirdiğim ve okuduğum tablodaki kilitleri arayan bir WHILE döngüsü kullandım. NetBalancer'ı sunucuya yükledim ve sunucunun ağ bağlantısındaki ağ gecikmesini taklit etmek için kullandım.

İşte bulduğum:

  • İstemciye fazla veri döndürmeyen ifadelerde gecikmenin kilitleme üzerinde etkisi yoktur. En fazla birkaç yüz baytlık veri döndürüyordum. Makinemdeki işlem, kilitleri tutan 250 ms'lik bir WAITFOR'a sahipti ve ağ gecikmesini 5000 ms'ye yükselttiğimde, kilit süresi 250 ms'ye yakın kaldı.
  • Çok fazla veri döndüren ifadelerde gecikme kesinlikle kilitlemeyi etkiler On binlerce satırı istemciye geri döndüm ve gecikme olmadan kilit süresi kısaydı. Gecikmeyi arttırdığımda, tüm verileri alana kadar kilitler devam etti.

Bundan, veri ağ arabelleğine uyduğu sürece gecikmenin önemli olmadığı sonucuna varıyorum. SQL, ağ arabelleğine çok fazla veri koymak zorunda kalırsa, gecikme bu arabelleğin yedeklenmesine neden olur ve SQL, sorgu sonucunun tümünü arabelleğe yerleştirene kadar tablo kilitlerini tutar.


İlginç sonuçlar. Hangi istemci programı / kütüphanesi bu?
James L

İyi şeyler. Bunun için biraz daha fazla zaman geçirme ve bunun gerçekleştiği sonuç boyutunu belirleyip belirleyemediğiniz herhangi bir şans?
Mark Storey-Smith

@ MarkStorey-Smith Kesin bir değer elde edebileceğimi sanmıyorum ve hiç şüphesiz makineye göre değişebilir. Gönderen vircom.com/security/improve-sql-nic-performance o yerel NIC üzerinde bir ayardır ve benim veritabanı sunucusu üzerinde bir 'otomobil' olarak ayarlandı gibi görünüyor
Evan M

@James Her iki makinede de sadece SSMS kullandım
Evan M

0

Yüksek gecikmeli bir ağ üzerinden MSSQL veritabanına tek bir çağrı yapıyorsam, bu gecikmeler nedeniyle tablo kilitleri oluşacak mı?

Bir sorgu tetiklendiğinde ve SQL Server tarafından tamamlandığında sonuçları üretir, çıktı arabelleğine yerleştirir ve istemciye gönderir ve daha sonra sonucu Çıktı arabelleğinden alır. SQL Server, sorgu istemciden alınmadığı sürece sorgu tarafından tutulan kilitleri serbest bırakmaz. Bu da engellemeye neden olabilir.

Edit: Evan Bu MS destek makalesine başvurabilirsiniz

Bölüm 3

Karşılık gelen İstemci Uygulaması Tüm Sonuç Satırlarını Tamamlamaya Getirmeyen SPID Neden Olduğu Engelleme

Sunucuya bir sorgu gönderdikten sonra, tüm uygulamalar hemen tüm sonuç satırlarını tamamlamaya getirmelidir. Bir uygulama tüm sonuç satırlarını getirmezse, kilitler tablolarda bırakılarak diğer kullanıcıları engelleyebilir. SQL deyimlerini sunucuya şeffaf olarak gönderen bir uygulama kullanıyorsanız, uygulamanın tüm sonuç satırlarını getirmesi gerekir. Bunu yapmazsa (ve bunu yapılandıramazsa) engelleme sorununu çözemeyebilirsiniz. Sorunu önlemek için, kötü davranan uygulamaları bir raporlama veya karar destek veritabanıyla sınırlandırabilirsiniz.


Cevabınız için teşekkürler Shanky! Bunun herhangi bir yerde belgelenip belgelenmediğini biliyor musunuz?
Evan M


5
Bu doğru değil.
Mark Storey-Smith

Bu doğru görünüyor 'uygulama tüm sonuç satırları getirmez, kilitleri masalarda bırakılabilir, diğer kullanıcıları engeller. SQL deyimlerini sunucuya şeffaf olarak gönderen bir uygulama kullanıyorsanız, uygulamanın tüm sonuç satırlarını getirmesi gerekir. Bunu yapmazsa (ve bunu yapılandıramazsa) engelleme sorununu çözemeyebilirsiniz. Sorunu önlemek için, kötü davranan uygulamaları bir raporlama veya karar destek veritabanıyla sınırlandırabilirsiniz. ' Daha genel anlamda konuşuyordum. Buradan okuyabilirsiniz support2.microsoft.com/kb/224453
Shanky

4
@Shanky Büyük bir tablo oluşturun. SELECT *adresinde ondan READ COMMITTEDbaşka birini SSMS bağlantısı, monitör kilitler. Herhangi bir zamanda kaç tane kilit olduğunu görüyorsunuz?
Mark Storey-Smith
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.