Bu makalede sp_whoIsactive ve sp_who2 komutlarını detaylı bir şekilde görmüş olacağız. sp_who2, sistemdeki tüm aktif bağlantılar, işlemler, ve oturumlarla ilgili bilgileri gösterir. Sonlanmış oturumlar bile geçici olarak belirli bir süre tutulmaktadır. Bu komut, SQL Server’da kimlerin bağlı olduğunu, hangi işlemlerin aktif olduğunu ve bu işlemlerin durumlarını anında görmenizi sağlar.

Bu komut, mevcut bağlantılar ve işlemler hakkında ayrıntılı bir tablo döndürür. Çıktıdaki veriler, genellikle işlem veya bağlantı seviyesinde bir sorun tespit etmeye yardımcı olur. Örneğin, blokajlar (locks), bekleme durumları (waiting), ve yüksek CPU veya IO kullanan işlemler hakkında bilgi verir.
sp_who: Daha basit bir versiyonudur ve genellikle temel oturum bilgilerini gösterir. Örneğin, sadece SPID, durum ve login gibi bilgileri içerir.
sp_who2: Daha ayrıntılı bilgiler sunar ve bekleme türleri, CPU kullanımı, disk IO, blokajlar gibi ek bilgileri içerir. Bu nedenle, daha kapsamlı bir analiz yapmak için genellikle sp_who2 tercih edilir. SQL Server’a yerleşik olarak gelir, ekstra bir kurulum gerekmez. Genellikle performans indexs oluşturma işlemlerinde anlık olarak session takip etmek için kullanılır. sp_whoIsactive’de göremediğimiz işlemi burada görebiliriz. Örnek olacak olursak 8 cpu ile çalıştırılan bir işlem sessionı üzerinde çalıştırıldığında session üzerindeki cpu sayısını ve durumunu göstermektedir.
Not: Cost treeshold paralelism değeri yüksek verilirse herhangi bir index veya maintance işlemlerinde kullanıcının verdiği maxdop oranı yüksek olsa bile sp_who2 komutu ile baktığımızda 1 tane görülmektedir. Sebebi ise yaptığımız maintance işleminin cost treshold paralelism değerini geçmemesidir.
sp_whoIsActive, SQL Server’da performans izleme, sorun giderme ve aktif sorgular ile işlemleri takip etmek için kullanılan bir sistem saklı prosedürüdür. Bu prosedür, SQL Server’daki aktif bağlantılar, beklemeler, blokajlar (blocking), kaynak kullanımı (CPU, IO) ve daha fazlasıyla ilgili ayrıntılı bilgi sağlar. sp_whoIsActive, Adam Machanic tarafından yazılmış ve yazılımcılar tarafından daha fazla özellik sunan bir üçüncü taraf saklı yordamıdır. Bu komut, sp_who2’ye kıyasla daha fazla bilgi sağlar, performans izlemesi konusunda daha kapsamlıdır ve blokajlar, beklemeler, IO ve CPU kullanımı gibi daha ayrıntılı veriler sunar. SQL Server’a yerleşik olarak gelmez, ancak SQL Server’a manuel olarak kurulması gerekir.
sp_whoIsActive, SQL Server’da aktif olarak çalışan sorgular, bekleme türleri, kilitler, blokajlar, işlemci ve disk kullanımı gibi detaylı performans bilgisi sağlar. sp_who2 ve sp_who gibi daha basit komutlara göre çok daha ayrıntılı bir analiz sunar.
sp_whoIsActive, üçüncü taraf bir yordamdır ve SQL Server’a manüel olarak kurulması gerekir. Yöneticiler, GitHub veya diğer kaynaklardan bu komut dosyasını indirip, veritabanına yüklemeleri gerekir.
İlgili makale sayesinde sp_whoIsactive sonucunda dönen değerleri bir tabloya kaydedip daha sonra kontrol işlemleri içim kullanabiliriz.
sp_whoIsActive komutunun birçok parametresi vardır ve bu parametreler, çıktıyı filtreleyerek daha spesifik bilgiler elde etmenizi sağlar. @show_sleeping_spids parametresi de bu parametrelerden birisidir.
Bu parametre 3 farklı değer alabilir:
– 0: Sadece aktif çalışan oturumları gösterir (varsayılan)
– 1: Sistem oturumları dahil tüm uyku durumundaki oturumları gösterir
– 2: Sadece kullanıcı oturumlarını ve açık transaction’ı olan sistem oturumlarını gösterir
Aşağıdaki komut, sadece aktif olan bağlantıları gösterecektir.
EXEC sp_WhoIsActive @show_sleeping_spids = 0;
Aşağıdaki komut, sadece uyuyan (sleeping) veya diğer tüm işlemleri gösterir.
EXEC sp_WhoIsActive @show_sleeping_spids = 1;
Diğer Parametreler:
sp_whoIsActive’nin daha birçok parametresi vardır ve bunlar filtreleme işlemleri yapmanızı sağlar. whoIsactive komutunun üzerine gelerek ilgili parametreler görülebilir. Sp_whoIsactive sonucunda gelen kololunların başlıkları belirtilmektedir.
sp_WhoIsActive @output_column_list = '[database_name], [sql_text], [session_id], [wait_info]';
Özetle:
sp_whoIsActive, SQL Server’daki aktif oturumlar, sorgular, bloklamalar ve performans verileri hakkında derinlemesine bilgi sağlar. Bu komut, SQL Server yöneticilerinin (DBA’ların) sistemdeki aktif işlemleri izlemesine, performans sorunlarını teşhis etmesine ve kaynak kullanımını analiz etmesine yardımcı olur. sp_who2 gibi basit komutlara göre çok daha kapsamlı bir araçtır ve büyük, karmaşık SQL Server ortamlarında daha faydalıdır.
Aşağıdaki komut sayesinde anlık çalışan sorgularda maliyetli cpu değerlerini göstermektedir.
SELECT
r.session_id,
r.status,
r.cpu_time,
r.start_time,
r.total_elapsed_time,
r.logical_reads,
r.reads,
r.writes,
s.text AS QueryText
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS s
ORDER BY r.cpu_time DESC;

Not: Aşağıdaki komut ile anlık çalışan sorgularda belirtilen login’le ilgili değerleri getirmektedir.
EXEC sp_WhoIsActive
@filter_type = 'login',
@filter = 'login_name'
Yukarıdaki komutu sp_whoIsactive’deki bazı kolonlar için kullanabiliriz. Veritabanı aramak için login kısmına database filter kısmına veritabanı adını yazmamız gerekmektedir.
sp_whoIsactive @filter_type='database',
@filter='DB_AKTARIM'
sp_whoIsactive @filter_type='host',
@filter='NODE1'
Aşağıdaki komutla sorgularınız hangi program üzerinde çalıştığını görebilirsiniz.
sp_whoIsactive @filter_type='program',
@filter='Microsoft® Windows® Operating System'
Aşağıdaki komutla belirlediğimiz kolon üzerinde sıralama işlemi yapabiliriz.
sp_WhoIsactive @sort_order='[cpu] desc'
sp_WhoIsactive @sort_order='[reads] desc'
sp_WhoIsactive @sort_order='[used_memory] desc'
@get_plans parametresi sorgu planlarını almak için kullanılır.
EXEC sp_WhoIsActive
@get_plans = 1
Sadece belirli sorguların planı seçilmek isteniyorsa aşağıdaki şekilde yapılmaktadır.
sp_whoIsactive 1649, @get_plans=1
| Değer | Açıklama |
|---|---|
| 0 | Sorgu planlarını getirme (varsayılan) |
| 1 | XML sorgu planlarını getir |
| 2 | Sorgu planlarını metin olarak getir (SQL 2014+) |
Belirli Bir SPID için Plan Almak için aşağıdaki komut kullanılır.
EXEC sp_WhoIsActive
@get_plans = 1,
@filter = '55' -- SPID numarası
Sadece Uzun Süren Sorguların Planlarını Almak için aşağıdaki komut kullanılmaktadır.
EXEC sp_WhoIsActive
@get_plans = 1,
@not_filter_type = 'duration',
@not_filter = '00:00:05' -- 5 saniyeden uzun sürenler
Aşağıdaki ifade sorguların üzerinde lock varsa bunu bize vermektedir.
EXEC sp_WhoIsActive @show_sleeping_spids=0,
@get_locks = 1
Aşağıdaki parametre ile sp_whoIsactive procedure yapısında neleri kullanabildiğimizi açıklamaları ile birlikte görebiliriz.
sp_whoIsactive @help=1

sp_whoIsactive @get_full_inner_text=1: Normalde sql_text kolonu sadece o an çalışan tek bir ifadeyi (statement) gösterir. Bu parametreyi kullandığınızda, o ifadenin içinde bulunduğu tüm batch’i veya saklı yordamın (stored procedure) tam içeriğini görebilirsiniz. Özellikle uzun kod blokları içindeki bir sorgunun bağlamını anlamak için kritiktir. 0 ifadesi default olandır.
Tüm “batch” metnini blok halinde görürsünüz. Eğer bu bir Stored Procedure (Saklı Yordam) ise, prosedürün içindeki o an çalışan satırı değil, tüm prosedür içeriğini görürsünüz.
sp_whoIsactive @get_outer_command=1: Bu komut, sonuç kümesine sql_command adında yeni bir kolon ekler. Bu kolon, çalışan iç sorguyu tetikleyen en dıştaki çağrıyı (örneğin uygulamanın gönderdiği ana sorguyu veya yordam çağrısını) gösterir. İç içe geçmiş çağrılarda “asıl tetikleyici”nin kim olduğunu bulmanızı sağlar. Bir veritabanında yüzlerce farklı prosedür aynı tabloyu sorguluyor olabilir. Eğer sadece sql_text’e bakarsanız, o an çalışan SELECT sorgusunun hangi ana iş sürecinden (Rapor mu? Fatura kesme mi? Stok güncelleme mi?) geldiğini anlayamazsınız. @get_outer_command size o zincirin en başındaki “tetikleyici” komutu verir.
Not: Bazen sp_whoIsactive çekildiğinde EFSavePoint yapısı görülmektedir.

Savepoint, uzun ve karmaşık bir veritabanı işleminin (transaction) ortasına konulan bir “bayrak” veya “geri dönüş noktasıdır.” Normal bir transaction’da hata oluştuğunda ROLLBACK komutu her şeyi en başa sarar. Savepoint kullanıldığında ise, hata oluşursa işlemin tamamını iptal etmek yerine sadece en son koyduğunuz “bayrak”tan sonrasını iptal edip, o noktadan devam edebilirsiniz.
Görüntüde bir işlemin kısmi başarısızlık senaryosu var:
- SAVE TRANSACTION [EFSavePoint]: Entity Framework Core (EF Core), işleme başlamadan önce bir “güvenli nokta” oluşturmuş.
- ROLLBACK TRANSACTION [EFSavePoint]: Aradaki sorgu hata aldığı için (örneğin bir kısıtlama hatası veya timeout), sistem her şeyi iptal etmek yerine sadece o “güvenli nokta”dan sonrasını geri almış.
Bu iki yapı (SAVE ve ROLLBACK), veritabanı yöneticisi (DBA) perspektifinden bakıldığında şu maliyetleri getirir:
- Ek Komut Maliyeti (Overhead): Uygulama her SaveChanges() dediğinde, SQL Server’a fazladan bir “Kayıt noktası oluştur” mesajı gider. Bu, ağ trafiğini ve SQL Server’ın komut işleme (parsing) yükünü artırır.
- Transaction Log (LDF) Şişmesi: Savepoint’ler işlem günlüğünde (Log) yer tutar. Sık sık savepoint oluşturulması, özellikle yüksek trafikli sistemlerde LDF dosyasının büyümesine ve disk I/O’sunun artmasına neden olur.
- Uzun Süreli Kilitler (Blocking): Bir ROLLBACK gerçekleştiğinde, SQL Server o noktaya kadar yapılan değişiklikleri geri sarmak için kaynak tüketir. Bu esnada ilgili satırlar üzerindeki kilitler (locks) serbest bırakılmaz, bu da diğer kullanıcıların sp_whoisactive üzerinde beklemesine (blocking) yol açar.
- Hatalı Döngüler: Eğer ekran görüntüsündeki gibi sürekli bir ROLLBACK varsa, uygulamanız sürekli hata üretiyor demektir. Bu, veritabanı motorunun sürekli “yap-boz” (undo/redo) işlemi yapmasına neden olarak CPU’yu gereksiz yere yorar.
- Eğer “kısmi geri dönüş” (partial rollback) özelliğine ihtiyacınız yoksa (yani bir hata olduğunda tüm işlemin iptal olması sizin için uygunsa), EF Core üzerinden bu özelliği devre dışı bırakın. Bu, SQL Server üzerindeki yükü ciddi oranda azaltacaktır.
Kapatmak için SQL Server tarafında değil, kod tarafında şu ayar yapılır:
// DbContext ayarlarında Savepoint'i devre dışı bırakma
optionsBuilder.UseSqlServer("connection_string",
o => o.DisableRollbackOnUpdateStrategy());
Normal bir transaction’da Atomicity (Atomiklik) kuralı geçerlidir: Ya hepsi veritabanına yazılır (1), ya da en ufak bir hatada her şey geri alınır (0).
Savepoint ise bu “ya hep ya hiç” kuralına bir esneklik getirir. İşlemi küçük parçalara böler.
- Normal Transaction: Bir hata aldığında ROLLBACK komutu transaction’ın başladığı (BEGIN TRANSACTION) ana döner.
- Savepoint: Hata aldığında ROLLBACK TRANSACTION SavePointName komutu ile sadece o bayrağın dikildiği ana döner. Bayraktan önceki işlemler (örneğin ilk 3 başarılı adım) bellekte/logda “tamamlanmaya hazır” beklemeye devam eder.
SQL Server’da Log dosyasının boşalabilmesi (Truncate/Reuse) için ilgili kayıtların “MinLSN” (Minimum Log Sequence Number) değerinin ilerlemesi gerekir. Bir transaction açık olduğu sürece, o transaction’ın en başından beri yazdığı tüm log kayıtları “Active Log” olarak kabul edilir.
- Truncate Engelleyici: Savepoint kullanıldığında transaction hala “Açık” (Open Transaction) durumdadır. Sen 10 adım atıp 8. adıma geri dönsen bile, 1. adımdan itibaren yapılan tüm işlemler hala transaction’ın bir parçasıdır.
- Checkpoint Etkisizliği: SQL Server arka planda CHECKPOINT çalıştırsa bile, açık olan bir transaction’a ait log kayıtlarını temizleyemez (Truncate edemez).
- Log Zinciri: Savepoint ile sürekli “deneme-yanılma” yapılıyorsa ve ana transaction bir türlü COMMIT veya tam ROLLBACK edilmiyorsa, log dosyası o transaction bitene kadar büyümeye mecburdur. Çünkü SQL Server, olası bir tam geri dönüş (Full Rollback) veya sistem çökmesi durumu için o transaction’ın en başındaki halini saklamak zorundadır.
Özetle: Savepoint ile geri döndüğün an işlem bitmiş sayılmaz. Transaction hala canlıdır ve SQL Server “belki en başa da dönmek istersin” diye en baştan itibaren tüm log’u kilitleyerek temizlenmesini engeller.
Başka bir makalede görüşmek dileğiyle..
İnkar edenler için çetin bir azap vardır. İman edip salih ameller işleyenler için ise bir bağışlanma ve büyük bir mükafat vardır. Fâtır-7
