SQL Server kilitlerinde garip durum

Karşılaştığımız durum garip ya da bana öyle geliyor. Ortak kaynaklara kilit (lock) koymaması gerektiği halde SQL Server’ın bazı sorguları beklettiğini görüyoruz. Durumu açıklamaya çalışayım. Öncelikle elimizde iki alanı olan bir tablo var:

  • id bigint identity
  • content varbinary(8000)

bu tablodan bir seferde 10 kayıt seçip bunu siliyoruz. Aynı anda başka bir thread’in (ya da uygulama) aynı işi diğer bir 10 kayıt üzerinde de yapabilmesini istiyoruz. Bu yüzden silme sırasında kayıt seviyesinde kilit kullanmak ve okurken de kilitli kayıtları gözardı etmek istiyoruz, böylece kilitlere takılmayacağız. Sorunu oluşturabilmek için demostrasyon maksatlı olarak transaction’ı commit etmiyoruz. İşte sorgu:

set transaction isolation level read committed
begin tran

select top 10 * into #t2temp from T2 with (readpast)
delete from T2 where T2ID in (select T2ID from #t2temp with (nolock))
select * from #t2temp
--commit

Normal şartlarda bu sorguyu farklı Management Studio pencerelerinden çalıştırdığınız zaman herhangi bir sorun olmadan paralel olarak çalışabiliyorlar. Her satır için bir exclusive key lock konuyor ve bir birleriyle çakışmıyorlar. Örneğin üç pencereniz varsa bunlar farklı satırları okuyacağından 30 eXclusive lock ve ayrıca bir takım page ve object IX/IU (intent) lockları ile işlemler gerçekleştirilebiliyor.

Ancak neden olduğunu bilmediğim bazı durumlarda ortak bir satıra kilit koyarak diğer sorguların beklemesine neden olabiliyor. Aynı satırı hiç okumadığı düşünüldüğü zaman nasıl oluyor da aynı satıra kilit koyuyorlar, henüz anlayabilmiş değilim.

Birbirlerini bekler halde kilitlendiklerinde kilitlerin özeti şöyle gözüküyor:

DATABASE	S	52	1
DATABASE	S	53	1
DATABASE	S	56	1
DATABASE	S	57	1
KEY		U	53	1
KEY		U	56	1
KEY		U	57	1
KEY		X	52	10
OBJECT		IX	52	1
OBJECT		IX	53	1
OBJECT		IX	56	1
OBJECT		IX	57	1
PAGE		IU	53	1
PAGE		IU	56	1
PAGE		IU	57	1
PAGE		IX	52	10

son satırda kilitlerin toplam sayısı bulunuyor. Kilitli prosesleri görmek de mümkün:

52	0	MISCELLANEOUS
53	56	LCK_M_U                         	KEY: 8:72057594038648832 (1f001103463f)
56	52	LCK_M_U                         	KEY: 8:72057594038648832 (1f001103463f)
57	56	LCK_M_U                         	KEY: 8:72057594038648832 (1f001103463f)

Gördüğünüz gibi proses 56, proses 52’yi; 53 ve 57 de 56’yı bekliyor. Bu bile garip bir durum, çünkü 52 ve ardından 56 tamamlandığında 53 ve 57 hiç beklemeden tamamlanacak, oysa hepsi aynı anahtarı bekliyor.

Anahtarın içeriğini göremiyoruz, bildiğim kadarıyla böyle bir özellik yok. Ancak ID üzerindeki clustered index’i kaldırırsak doğrudan satır seviyesinde konan kilitten sayfaya ve oradan da veriye ulaşmak mümkün. Önceki denemelerimizde kilitli kaydın diğer sorgularda okunmayan bir kayıt olduğunu gördük. Bu yüzden de neden kilitlendiğini anlayamıyoruz.

Fikri olan varsa beri gelsin.

Bu yazı Bilgisayarlar ve Internet içinde yayınlandı. Kalıcı bağlantıyı yer imlerinize ekleyin.

2 Responses to SQL Server kilitlerinde garip durum

  1. kozsu dedi ki:

    Bir düzeltme: 53 ve 57 nolu prosesler 56’yı beklese de kilitler tekrar belirlenirken bu sorun ortadan kalkıyor ve son aşamadan önce 53 ve 57’den bir diğerini bekler hale geliyor..

  2. Tarık Kranda dedi ki:

    Hocam sadece fikir yürütüyorum; acaba kilitlenen satırların çakışması durumu aslında aynı satıra denk gelmekten değil de, key haricinde listelenen page ve object kilitlerinden kaynaklanıyor olabilir mi? Yani demek istediğim siz satır bazlı kilitleme yapıyorsunuz ama listeye göre page ler üzerinde de kilitlenme durumu oluşuyor. Peki farklı processlerin kilitlediği 2 farklı kayıt aynı page ‘ e denk gelirse böyle bir durum oluşabilir mi?

kozsu için bir cevap yazın Cevabı iptal et

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s