dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Runbook #26
sqlserver
LockingSEV2 · CİDDİ BOZULMA15-30 dakika / 15-30 minssysadmin / CONTROL SERVER / VIEW SERVER STATE

SQL Server Bloklama Zinciri: Baş Bloklayıcıyı Bulma ve Çözme

Zincirin başındaki oturumu bulur, açık transaction'ı tespit eder ve güvenli şekilde sonlandırır. Tekrarı önlemek için RCSI ve eşik ayarlarını anlatır.

İlişkili Metrik:M28M29
İlişkili Script:S41S49
#blocking#locks#kill#rcsi

Operasyonel Güvenlik ve Risk Uyarısı

Bu runbook müdahale adımları içerir; birçok adım yazma etkilidir (KILL, terminate, DROP, RESIZE). Önce test ortamında deneyin, üretimde adımları sırayla ve doğrulayarak uygulayın.

🟢 Salt Okunur (Read-Only)·🟡 Geri Alınabilir (Reversible)·🔴 Yüksek Etkili / Geri Alınamaz (High Impact)

1. Belirti / Symptom

- Sorgular uzun süre `LCK_M_*` beklemesinde, uygulama zaman aşımları.

- M28 (bloklanan işlem) eşiği aşıldı.

- Çok sayıda oturumda `blocking_session_id <> 0`.

2. Etki / Impact

Etkilenen tablolara erişen tüm istekler yavaşlar veya durur. Bağlantı ve thread havuzları dolabilir.

3. Teşhis / Diagnosis

🟢 Salt Okunur1. Bloklama ağacını görün (S41):
sql
SELECT r.session_id, r.blocking_session_id, r.wait_type, r.wait_time/1000 AS wait_sec,
       DB_NAME(r.database_id) AS db, s.login_name, s.host_name, s.program_name
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON s.session_id = r.session_id
WHERE r.blocking_session_id <> 0
ORDER BY r.wait_time DESC;
🟢 Salt Okunur2. **Baş bloklayıcı:** `blocking_session_id` listesinde olup kendisi bloklanmayan oturum. Çoğu zaman `dm_exec_requests` içinde görünmez (isteği yok, `sleeping` durumda ama transaction'ı açık).
sql
SELECT s.session_id, s.status, s.login_name, s.host_name, s.program_name,
       s.last_request_end_time, t.text AS last_sql
FROM sys.dm_exec_sessions s
LEFT JOIN sys.dm_exec_connections c ON c.session_id = s.session_id
OUTER APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t
WHERE s.session_id = <bas_bloklayici>;
🟢 Salt Okunur3. Açık transaction'ı doğrulayın (S49):
sql
DBCC OPENTRAN;   -- mevcut veritabanındaki en eski transaction
🟢 Salt Okunur4. Yorumlayın: `sleeping` + açık transaction = uygulama COMMIT/ROLLBACK göndermemiş (en sık). `running` + uzun = ağır DML.

4. Müdahale / Response

1. Sahibini ve işin kritikliğini kontrol edin (toplu veri yükleme ortasındaysa kesmek uzun rollback yaratır).

🔴 YÜKSEK RİSK / GERİ ALINAMAZ2. Baş bloklayıcıyı sonlandırın (açık transaction geri alınır):
sql
KILL <bas_bloklayici>;
KILL <bas_bloklayici> WITH STATUSONLY;   -- rollback ilerlemesi

**Rollback uzun sürebilir** (transaction ne kadar sürdüyse yaklaşık o kadar). Oturumu tekrar `KILL` etmek rollback'i hızlandırmaz.

3. **Önleme:**

- Okuma/yazma çakışmasını azaltmak için **RCSI** değerlendirin (uygulamayı test edin, TempDB version store yükü artar):

sql
ALTER DATABASE VeritabaniAdi SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE;

- Bloklanan süreyi raporlamak için eşik:

sql
EXEC sp_configure 'blocked process threshold (s)', 20; RECONFIGURE;

- Uygulamada transaction'ları kısa tutun, `SET LOCK_TIMEOUT` kullanın, eksik indeksler nedeniyle geniş kilitlenen sorguları düzeltin (S41 sonuçlarında tarama/yüksek okuma).

5. Doğrulama / Verification

- Adım 1 sorgusu boş, M28 normale döndü.

- Bekleyen oturumlar tamamlandı, uygulama hata oranı düştü.

- Neden (uygulama bug'ı, toplu iş, eksik indeks) kaydedildi.

6. Geri Alma / Rollback

- `KILL` geri alınamaz. Uygulama transaction'ı yeniden denemelidir.

- RCSI geri almak: `ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT OFF WITH ROLLBACK IMMEDIATE;`.

Diğer SQLSERVER Runbook'ları