Deadlock Nedir? Extended Events ile Deadlock Nasıl İzlenir

Deadlock iki veya daha fazla transactionların/proseslerin birbirini kilitlemesi ve birbirini beklemesi olarak kısaca açıklayabiliriz. Örnekle anlatacak olursak elimizdeki bir ürünü iki müşteri aynı anda satın almak istediğinde bir kilitlenme meydana gelir iki kişiden birinin vazgeçmesi gerekmektedir ki diğeri ürünü satın alabilsin aksi taktirde ne zaman biteceği belli olmayan bir beklemenin içine girebiliriz ya da olaya biz müdahale olarak ürünü birine vererek diğer müşteriyi göndermemiz gerekecektir.

Resim 1

SQL Server tarafında bu olay Resim 1’deki gibi Transaction 1 ,  A tablosunu kilitledikten sonra B tablosuna erişmek istiyor ama Transaction 2’nin B tablosunu kilitlemesinden dolayı bekliyor. Aynı şekilde Transaction 2 , A tablosuna erişmek için Transaction 1 tarafından A tablosuna konulan kilidin kalkmasını bekliyor. Burada SQL Server olaya müdahale olarak timeout süresinden sonra Rollback maliyeti daha az olan sorguyu kurban(victim) olarak seçiyor ve kilidi kaldırıyor ve victim transactionı rollback yapıyor

Resim 2

Şimdiye kadar tablo olarak ifade etsek de SQL Server daha küçük ve büyük birimleri kilitleyebilir. Bunlara bakacak olursak

RID
KEY
PAGE
EXTENT
HoBT
TABLE
METADATA
ALLOCATION_UNIT
DATABASE

Bir satırlık kilitlenmeden page,tablo veya veri tabanına kadar büyüyen bir kilit mekanizması bulunmaktadır. Bunların detayına buradan ulaşabilirsiniz

Ufak bir örnekle bu işleyişin SQL Serverda nasıl gerçekleştiğini inceleyelim

Öncelikle 2 adet tablo oluşturmakla ve veri girmekle başlıyorum

Resim 3

DROP TABLE IF EXISTS Table_A
  CREATE TABLE Table_A (Id INT PRIMARY KEY, Brand VARCHAR(50))
  GO
  INSERT INTO Table_A VALUES(1,'Mercedes')
  INSERT INTO Table_A VALUES(2,'BMW')
  GO
  DROP TABLE IF EXISTS Table_B
  CREATE TABLE Table_B (Id INT PRIMARY KEY, Brand VARCHAR(50))
  GO
  INSERT INTO  Table_B VALUES(1,'Seat')
  INSERT INTO Table_B VALUES(2,'VW')
GO  

Sırada Update sorgularımız iki ayrı transaction olarak başlayak şekilde

Resim 4

BEGIN TRAN
  UPDATE Table_B SET Brand ='Seat Cupra' WHERE Id=1
  WAITFOR DELAY '00:00:10'
  UPDATE Table_A SET Brand ='Mercedes-Benz' WHERE Id=1
COMMIT TRAN

 BEGIN TRAN
  UPDATE Table_A SET Brand ='Mercedes Benz' WHERE Id=1
  WAITFOR DELAY '00:00:10'
  UPDATE Table_B SET Brand ='Cupra' WHERE Id=1
  COMMIT TRAN

Yeri gelmişken “EXEC sp_lock” stored prosedürü yardımıyla o an oluşan kilitlenmeleri inceleyebiliyoruz. Resim 5 de gördüğümüz üzere sorgularımız çalışmaya devam ederken SPID 62 ve 64 tarafında kilitlenmeler gerçekleşmiş.

Resim 5

Ve sonuç bir transaction kurban olarak seçilerek rollback gerçekleşti diğer transaction başarıyla tamamlandı.

Resim 6

Peki uygulama tarafında oluşabilecek Deadlockları nasıl izleyeceğiz. Burada Extended Events yardımımıza koşuyor. SSMS içerisinde  Management altında Extended Events > Sessions> New Session Wizard diyerek sihirbazı açıyoruz.

Resim 7

Oluşturacağımız sessiona bir isim veriyoruz ve bir sonraki adıma geçiyoruz.

Resim 8

Bir sonraki adımda bizden eventleri seçilmiş hazır şablonlardan birini mi yoksa kendimizin şablon kullanmadan mı devam edeceğini seçiyoruz. Burada ben alttaki seçeneği seçerek devam ediyorum

Resim 9

Arama yerine “deadlock” yazarak Resim 10 da gözüken eventleri seçiyorum ve devam ediyorum.

Resim 10

Sırada Capture Global Fields kısmında “sql_text” , “session_id” seçiyorum. Burada seçilerek bilgi verebilecek fazlasıyla metrik bulunuyor.

Resim 11

Bir sonraki aşamada Set Session Event Filters sekmesi bu sekme altında bir önceki adım olan “Capture Global Fields” bulunan alanlar ve başka alanlara göre filtreleme imkanı sunuyor.Örnek olarak sadece AdventureWorks veri tabanı olarak belirtebiliriz.

Resim 12

Son aşama olarak oluşturduğumuz bu Extened Eventimizin topladığı verileri bir dosyada saklayacak mıyız ona karar veriyoruz. Sadece anlık izlemek istiyorsak işaretli alanı doldurmadan devam ediyoruz. Eğer ki oluşan olayları kayıt etmek istiyorsak oluşan kayıtların hangi yola kayıt edileceğini ve oluşacak maksimum dosya boyutu gibi parametreleri ayarlıyoruz.

Resim 13

Son aşama olarak “Start the event session immediately after session creation” kutucuğunu işaretleyerek event oluşur oluşmaz başlamasını sağlıyoruz.

Resim 14

Oluşturduğumuz eventin üzerine sağ tıklayarak durdurabilir , başlatabilir veya canlı gerçekleşen olayları inceleyebiliriz.

Resim 15

Eventler durdurmadığımız müddetçe arka planda oluşan olayları kayıt altına almaktadır.Oluşan kayıtları incelemek için oluşturduğumuz eventin altında bulunan package dosyasını View Target Data diyerek açtığımızda kayıt altına alınan olayları inceleyebiliriz.

Resim 16

Extended Eventimiz oluşturduktan sonra yukarda ki örneğimize geri dönelim, iki transactionı tekrar başlatıyoruz dead lock oluşuyor ve bir tanesi rollback yapıldı

Resim 17

Eventimizi Resim 16 da ki gibi View Target Data diyerek incelediğimizde eventimiz oluştururken seçtiğimiz eventler, alanların aldıkları değerleri görebiliyoruz. Örnek olarak SQL Text, client app name, host name vb gibi

Resim 18

Seçtiğimiz eventlerden bir diğeri olan xml_deadlock_report  eventi altında Deadlock sekmesi altında oluşan deadlock hakkında grafik  üzerinden bilgi alabiliyoruz.

Resim 19

Oluşan grafiği incelecek olursak sol taraftaki üzeri çizilen transaction victim seçilen transactiondır. Üzerine geldiğimizde bu transactiona ait sql textini görebiliyoruz. Hangi transactionın hangi kaynağa erişmek istediği, kilit türü gibi birçok detaylı bilgiye ulaşabiliyoruz.

Bu yazımda sizlere veri tabanında dead lock kavramını bir örnekle anlatmaya çalıştım. Oluşan dead lockların extended event yardımıyla nasıl tespit edilebileceğinden bahsettim.

Faydalı olması dileğiyle

Leave a Reply

Your email address will not be published. Required fields are marked *