Bir sürecin kilitlenme kurbanı olmasının nedeni


106

5 ila 10 dakika arasında tamamlanması uzun süren bir Select işlemim var.
Şu anda MS SQL veritabanı motoru için bir ipucu olarak kullanmıyorum NOLOCK .
Aynı zamanda aynı veri tabanına ve aynı tablolara güncelleme ve ekleme yapan başka bir işlemimiz var.
İlk süreç başladı, yakın zamanda bir mesajla vaktinden önce sona erdi

SQLEXCEPTION: İşlem, başka bir işlemle kilit kaynaklarında kilitlendi ve kilitlenme kurbanı olarak seçildi.

Bu ilk işlem, diğer sitelerde aynı koşullarda, ancak daha küçük veri tabanlarında yürütülür ve bu nedenle söz konusu select ifadesi çok daha kısa bir süre alır (30 saniye civarında). Bu diğer sitelerde, diğer sitelerde kilitlenme mesajı almıyorum. Bu mesajı başlangıçta sorun yaşayan sitede de almadım, ancak veritabanı büyüdükçe bazı eşikleri aştığıma inanıyorum. İşte sorularım:

  1. Bir işlemin yürütülmesi için geçen süre, ilgili sürecin bir kilitlenme kurbanı olarak işaretlenme olasılığını artırabilir mi?
  2. Seçimi bir NOLOCK ipucu ile yürütürsem, bu sorunu giderir mi?
  3. Select deyimindeki WHERE yan tümcesinin bir parçası olarak kontrol edilen bir datetime alanının yavaş arama süresine neden olduğundan şüpheleniyorum. Bu alana dayalı olarak bir dizin oluşturabilir miyim? Tavsiye edilir mi?

1. noktaya kısmi cevap: Bir kilitlenmeyi zaman aşımıyla karıştırmayın. Bir zaman aşımından muzdaripseniz, bir işlemi bitirmek için harcanan zaman diğer iptalden sorumlu olabilir. Ayrıca, hangi kaynak üzerinde kilitlendiğinizi bilmek faydalı olacaktır (bu bir dizin mi yoksa bir tablo mu?).
NealB

1
DEADLOCK_PRIORITY YÜKSEK ALTER VERİTABANI AYARLA veritabanı adı SET MULTI_USER;
gstackoverflow

Yanıtlar:


129

S1: Bir işlemin yürütülmesi için geçen süre, ilgili sürecin bir kilitlenme kurbanı olarak işaretlenme olasılığını artırabilir mi?

Hayır. SELECT kurban çünkü sadece veri okumuştu, bu nedenle işlemin kendisiyle ilişkili daha düşük bir maliyeti var , bu yüzden kurban olarak seçildi:

Varsayılan olarak, Veritabanı Motoru kilitlenme kurbanı olarak, geri alınmasının en ucuz olduğu işlemi çalıştıran oturumu seçer . Alternatif olarak, bir kullanıcı, SET DEADLOCK_PRIORITYdeyimi kullanarak bir kilitlenme durumunda oturumların önceliğini belirleyebilir . DEADLOCK_PRIORITY, LOW, NORMAL veya HIGH olarak ayarlanabilir veya alternatif olarak (-10 ila 10) aralığındaki herhangi bir tam sayı değerine ayarlanabilir.

S2. Seçimi bir NOLOCK ipucu ile yürütürsem, bu sorunu giderir mi?

Hayır. Birkaç nedenden dolayı:

S3. Select deyimindeki WHERE yan tümcesinin bir parçası olarak kontrol edilen bir datetime alanının yavaş arama süresine neden olduğundan şüpheleniyorum. Bu alana dayalı olarak bir dizin oluşturabilir miyim? Tavsiye edilir mi?

Muhtemelen. Kilitlenmenin nedeni, neredeyse çok zayıf indekslenmiş bir veritabanıdır. 10 dakikalık sorgular o kadar dar koşullarda kabul edilebilir ki, sizin durumunuzda% 100 eminim ki kabul edilemez.

% 99 güvenle, kilitlenmenizin, güncellemelerle çelişen büyük bir tablo taramasından kaynaklandığını beyan ederim. Nedeni analiz etmek için kilitlenme grafiğini yakalayarak başlayın . Veritabanınızın şemasını büyük olasılıkla optimize etmeniz gerekecektir. Herhangi bir değişiklik yapmadan önce, Dizin Tasarlama konusunu ve alt makaleleri okuyun.


Kapsamlı cevabınız için teşekkür ederim. Sanırım hala bir sorum var. Neden sadece bir ortamda ve başka bir ortamda çıkmaz durumu yaşayayım? Yazılım aynı olsa bile. Cevabınız, Seçim sorgusunu çalıştırma süresinin bir fark yaratmadığını ve işlemin başarısız olmasına neden olan şeyin başlı başına bir Seçim sorgusu olması olduğunu gösteriyor. Peki neden yalnızca seçme sorgusunun yürütülmesi uzun sürdüğünde?
Elliott

4
Sorgunun uzunluğu , kilitlenme kurbanının seçilmesinde bir fark yaratmaz . Kilitlenmeye en az iki faktörle neden olmada bir fark yaratır: 1) basit olasılıklar. Sorgu ne kadar uzunsa, eşzamanlı güncellemelerle çakışması ve kilitlenmelerle karşılaşma olasılığı o kadar yüksektir. 2) daha büyük bir tablo, kilitlenmelere açık, tamamen farklı bir sorgu planı kullanabilir.
Remus Rusanu

12

İşte bu özel kilitlenme sorununun gerçekte nasıl oluştuğu ve gerçekte nasıl çözüldüğü. Bu, günlük 130 bin işlemin gerçekleştiği oldukça aktif bir veritabanıdır. Bu veritabanındaki tablolardaki dizinler orijinal olarak kümelenmiştir. Müşteri bizden dizinleri kümelenmemiş hale getirmemizi istedi. Biz bunu yapar yapmaz, çıkmaz başladı. Dizinleri kümelenmiş olarak yeniden oluşturduğumuzda, kilitlenme durdu.


34
Biri nedenini açıklayabilir mi? (Sihirli çözümler pek yardımcı olmuyor)
OGrandeDiEnne

2
Bu adam bunu gönderisinde açıklıyor: mssqltips.com/sqlservertip/2517/…
siga0984

6

Buradaki cevaplar denemeye değer, ancak kodunuzu da gözden geçirmelisiniz. Polyfun'un cevabını burada özellikle okuyun: SQL Server 2005 ve C # uygulamasında kilitlenmeden nasıl kurtulurum?

Eşzamanlılık sorununu ve sorgularınızda "with (updlock)" kullanımının, kodunuzun tam olarak ne yaptığına bağlı olarak, kilitlenme durumunuzu nasıl düzeltebileceğini açıklar. Kodunuz bu kalıbı takip ediyorsa, kirli okumalara başvurmadan önce bu muhtemelen daha iyi bir çözümdür.


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.