Evet sevgili SQL Server sevenler, sevmek zorunda kalanlar ve nereden bulaştım bu
işe diyenler :). Yeni bir bölüme başlıyoruz
"DBA Toolkit" amacımız
genelde DBA ler tarafından kullanılan (ki en çok kendimizin kullandığı) veya kullanılmasını
tavsiye edeceğimiz scriptleri tanıtıp paylaşacağız.
Serimize hayat kurtaran baş tacımızla :) başlıyoruz.
Tüm DBA ler için "Sistem yavaşladı" veya "Kitlendik" sözlerini duydumu yoğun arayış
başlıyor demektir. Önce "Activity Monitor" açılmaya çalışılır açılırsa sorgular
kontrol edilir eğer açılmazsa araştırma devam eder ve ellerinde bulunan query lerle
(sp_who veya sp_who2 en çok kullanılanı) inceleme yapılmaya devam edilir ve uzun
bir arayıştan sonra (bu arada kitlenme bitmiş olabilir :):)) "SQL de sorun yok"
sözleriyle biter.
sp_WhoIsActive Download
İndirdiğiniz scripti direk SSMS üzerinde execute ederek sistemimize ekliyoruz, master
db üzerinde çalışan bir SP olduğundan dolayı belirli yetkilere sahip olmanız gerektiğini
hatırlatmama gerek yoktur herhalde :). Siz yapamıyorsanız sysadmin'e söyleyip (yararını
görmesi için makaleyi okutabilirsiniz) execute ettirebilirsiniz.
Size sisteme aldığınız script için "New Query" diyerek yeni bir sayfa açıp execute
etmek kalıyor.
EXEC sp_WhoIsactive
Görüldüğü gibi sistem hakkında fazlasıyla bilgi içeriyor.
Kullanım parametrelerini öğrenmek için
EXEC sp_whoisactive @help = 1
Çok fazla kolon geliyor ben sadece belirli kolonları istiyorum acaba "Adam" amca
bunları düşünmüş mü? dediğiniz duyar gibiyiz ve cevabımız "Yapmış be adam :):) "
EXEC sp_WhoIsActive
@find_block_leaders = 1
, @get_task_info = 1
, @get_additional_info = 0
, @output_column_list = '[session_id][block%][login_name][host%][host_process_id][program%][sql_text][wait_info]'
, @sort_order = '[blocked_session_count] DESC'
DBA ler için belki de en önemli bölümü (her türlü gideri varda :) ) sistemi bloklayan
sorguyu çok hızlı bir şekilde gösteriyor olması. Bunun için kolonlar içerisinde
"blocking_session_id" kontrol etmemiz yeterli oluyor. Burada yazan SPID bizi kilitleyen
sorgunun ID si bu SPID yi kontrol ettikten sonra beklemeye devam edilebilir veya
hiç istemesekte yapmak zorunda olduğumuz "Kill" komutunu çalıştırabiliriz.
EXEC sp_whoisactive @help = 1
Sorgularınız uzun olduğunda XML olarak çıkan sonuç sizi tatmin etmeyebilir, bunun
için alttaki şekilde çalıştırabiliriz.
EXEC sp_whoisactive @format_output = 0
SQL Server'da gelen connectionların bazıları sleeping de beklerler bunları bulabilmek
için (Yazılımcıların açık bıraktığı sorguları görmekte bire bir :) )
EXEC sp_WhoIsActive @show_sleeping_spids = 2
Sorguların query_plan larını görebilmek için.
EXEC dbo.sp_WhoIsActive @get_plans = 1, @get_task_info = 2
Çok fazla veri tabanıyla çalışan DBA'ler için güzel bir parametre de filtre parametresi.
-- İstediğimiz veri tabanına göre filter koyuyoruz
EXEC sp_whoisactive @filter_type = 'database', @filter = 'master'
GO
-- Görmek istemediğimiz veri tabanına göre filter koyuyoruz
EXEC sp_whoisactive @not_filter_type = 'database', @not_filter = 'master'
Son olarak da sp_WhoIsActive in sorgu sonuçlarını bir tabloda toplayıp bunlar üzerinde
sonradan analiz yapmaya çalışalım.
Adım 1:
Öncelikle alt yapımızı hazırlayalım.
-- sp_WhoIsactive nin sorgu sonucuna göre birr tablo create ediyoruz
DECLARE @History_table VARCHAR(4000) ;
SET @History_table = 'spWhoIsActiveHistory';
DECLARE @schema VARCHAR(4000) ;
EXEC sp_WhoIsActive
@get_transaction_info = 1,
@get_plans = 1,
@return_schema = 1,
@schema = @schema OUTPUT ;
SET @schema = REPLACE(@schema, '
', @History_table) ;
-- PRINT @schema
EXEC(@schema) ;
Adım 2:
Hazırladığımız tabloya "@destination_table" parametresini kullanarak belli aralıklarla
kayıt atacağız ve böylece geçmiş yönelik analiz yapabileceğiz. sp_WhoIsactive SP
sini çok farklı şekilde çalıştırabildiğimizi unutmayalım dikkatli olmanız gereken
nokta history tablosunu hangi parametrelerle oluşturduysak o parametrelerle ilerlememizdir.
Biz burada Execution planları almak istediğimizden dolayı "get_plans" parametresiyle
çalıştırdık. "EXEC sp_WhoIsActive @get_transaction_info = 1, @get_plans = 1"
DECLARE
@History_table VARCHAR(4000)
SET @History_table = 'spWhoIsActiveHistory';
-- Anlık olarak kayıtları ekliyoruz
EXEC dbo.sp_WhoIsActive @get_transaction_info = 1, @get_plans = 1,
@destination_table = @History_table;
-- Eklenen kayıtları kontrol ediyoruz
select * from spWhoIsActiveHistory order by collection_time desc
Adım 3 :
Bu kayıt işlemini belli bir tekrarla otomatik olarak yapmak isteyebiliriz.
DECLARE
@History_table VARCHAR(4000) ,
@msg NVARCHAR(1000) ;
SET @History_table = 'spWhoIsActiveHistory';
DECLARE @numberOfRuns INT ;
SET @numberOfRuns = 10 ;
WHILE @numberOfRuns > 0
BEGIN;
EXEC dbo.sp_WhoIsActive @get_transaction_info = 1, @get_plans = 1,
@destination_table = @History_table ;
SET @numberOfRuns = @numberOfRuns - 1 ;
IF @numberOfRuns > 0
BEGIN
SET @msg = CONVERT(CHAR(19), GETDATE(), 121) + ': ' +
'Lütfen bekleyin loglama devam ediyor...'
RAISERROR(@msg,0,0) WITH nowait ;
WAITFOR DELAY '00:00:05'
END
ELSE
BEGIN
SET @msg = CONVERT(CHAR(19), GETDATE(), 121) + ': ' + 'Loglama Bitmiştir..'
RAISERROR(@msg,0,0) WITH nowait ;
END
END ;
GO
-- Eklenen kayıtları kontrol ediyoruz
select * from spWhoIsActiveHistory order by collection_time desc
"Her yiğidin bir yoğurt yiyişi vardır" der atalarımız bu yüzden bu güzelim SP yi
kullanırken Bizde onlarca kolon içerisinde nelere çok dikkat ediyoruz onlardan bahsedeyim.
Hatırlarsak bu değerlere "EXEC sp_whoisactive @help = 1" yazarak ulaşabiliriz
• "[dd hh:mm:ss.mss]" - Tabii ki ilk sırada :) neye dikkat ediyorum
hangi query ne kadardır devam ediyor. Her uzun süren sıkıntılıdır diyemeyiz tabii
bununla birlikte sorumlusunu bulup bir mütaala :):) yapıyoruz.
• "[sql_text]" - Query içeriğini buradan görebiliyoruz.
• "[login_name]" - Query yi çalıştıran arkadaşı tespiti hızlandırıyor
:) Seni seçtim pikachu derken ispatınız oluyor :):)
• "[wait_info]" - Yine önemli kolonlardan biri özellikle blocking
yapan querylerde wait süresini gözlemliyorum query analizlerinde sıkıntılı bölgeye
odaklanmayı kolaylaştırıyor.
• "[blocking_session_id]" - Kritik kolonlardan biri, Query leri
blocklayan query'nin SPID sini gösteriyor.
• "[physical_reads]" - IO baskısı yapan queryleri üzerinde çalışma
yapmak için bakıyoruz. Tam bir rakam söylemek zor çünkü; bazen 10.000 yüksekken
bazen de 100.000 yüksek oluyor.
• "[query_plan]" - Query'nin Execution Planını görüp incelemek
için kullanıyoruz.
• "[percent_complete]" - özellikle Backup-restore işlemlerinde
direk baktığımız yer. "Abi bitmedi mi?" sorusunun canlı cevabı :):)
• "[host_name]" - Query hangi sunucudan geliyor onu buluyoruz ve
kaçağı tespit ediyoruz.
• "[database_name]" - Çalışan veri tabanını tespit ediyoruz.
• "[program_name]" - özellikle sisteme sızan :):) kaçak kod yazan
ki canlı örnekleri çoktur yazılımcı arkadaşlar kullanıcı adı ve şifresini öğrendi
mi tutabilene aşkolsun :):).
Bir yazımızda böylece bitti, yeni makalelere blocking'siz select atmak üzere hoşçakalın
:).