Sună telefonul la 3 dimineața. „Baza de date e lentă. Totul dă timeout.”
Deschizi laptopul, te conectezi, rulezi o interogare. Îți spune exact ce rulează, cine pe cine blochează, care interogări mănâncă CPU, care așteaptă disc, care țin lock-uri. Petreci următoarele cinci minute omorând sesiunea potrivită și viața revine la normal.
Acea interogare e sp_WhoIsActive. E procedura open-source de 20 de ani a lui Adam Machanic, și e cea mai utilă unealtă de răspuns la urgențe din arsenalul unui DBA. sp_BlitzFirst (parte din First Responder Kit) e versiunea ușor mai prietenoasă de la echipa lui Brent Ozar.
Instalează-le pe ambele. Mulțumește-mi mai târziu.
sp_WhoIsActive: clasica
Adam Machanic a scris-o pe la 2007. E standardul de aur pentru „cine rulează interogări pe serverul meu chiar acum”. Descarcă: whoisactive.com sau caută „sp_WhoIsActive github”.
Instalare: descarcă fișierul .sql, rulează-l pe master (sau pe baza ta DBA).
Apel de bază:
EXEC sp_WhoIsActive;
Returnează un rând per sesiune utilizator activă, cu coloanele:
- session_id — SPID-ul.
- start_time — când a început această cerere.
- sql_text — ce rulează (XML clicabil, deschide interogarea completă).
- login_name / host_name / program_name — cine apelează.
- database_name.
- wait_info — pe ce așteaptă, de cât timp.
- CPU, reads, writes — utilizarea resurselor de până acum.
- blocking_session_id — cine blochează această sesiune (dacă e cazul).
- status — running, suspended etc.
Sortează după CPU sau reads desc; rândurile de sus sunt interogările tale cele mai grele.
Diagnostic într-o linie:
wait_infoaratăLCK_M_X(42)— așteaptă ca sesiunea 42 să elibereze un lock exclusiv.blocking_session_id = 42— confirmă.- Rulează
EXEC sp_WhoIsActive @session_id = 42pentru a vedea ce face 42. - Sau omoară 42:
KILL 42.
Parametri utili
@get_plans = 1— include XML-ul planului de execuție.@get_locks = 1— arată toate lock-urile ținute de fiecare sesiune.@find_block_leaders = 1— sortează sesiunile astfel încât „liderul de blocaj” (cel care provoacă un lanț de blocaje) să fie sus.@sort_order = '[CPU] DESC'— alege sortarea.@get_task_info = 2— detalii verbose de task.
Combinația mea uzuală în urgență:
EXEC sp_WhoIsActive
@find_block_leaders = 1,
@get_plans = 1,
@get_locks = 1;
Tot ce ai nevoie pe un singur ecran.
Logarea sp_WhoIsActive într-un tabel
Pentru monitorizare continuă:
-- Creează tabelul de destinație
DECLARE @schema NVARCHAR(MAX);
EXEC sp_WhoIsActive @return_schema = 1, @schema = @schema OUTPUT;
SET @schema = REPLACE(@schema, '<table_name>', 'DBA.dbo.WhoIsActive_log');
EXEC (@schema);
-- Programează asta prin Agent la fiecare 60 de secunde
DECLARE @dest NVARCHAR(4000) = 'DBA.dbo.WhoIsActive_log';
EXEC sp_WhoIsActive @destination_table = @dest;
Acum ai un log rulant cu tot ce s-a rulat. Când cineva întreabă „ce s-a întâmplat la 2:15?”, știi.
sp_BlitzFirst: fratele „chiar acum”
Echivalentul lui Brent din First Responder Kit. Stil diferit față de sp_WhoIsActive; ambele sunt utile.
USE DBA;
EXEC sp_BlitzFirst;
Rulează 5 secunde implicit, eșantionând wait stats pe fereastra aceea. Îți dă imaginea de moment în loc de distribuția cumulativă a wait stats.
Output-ul e în stilul sp_Blitz, ordonat după prioritate:
- Top tipuri de wait curente.
- Interogări lungi în execuție acum.
- Utilizarea CPU în acest moment.
- Baza de date cu activitatea cea mai mare.
@SinceStartup = 1 — în loc de eșantion de 5 secunde, arată stats-uri cumulative de la pornirea serverului.
@ExpertMode = 1 — mai multe coloane, diagnostic mai adânc.
Secvența mea implicită de triaj când sună telefonul:
sp_WhoIsActive @find_block_leaders = 1;— cine pe cine blochează?sp_BlitzFirst @ExpertMode = 1;— pe ce așteptăm, colectiv?- Alege cea mai mare problemă, acționează.
Zece secunde de tastare. În 90% din cazuri, cauza e evidentă din aceste două interogări.
Omorârea unei sesiuni
Când sp_WhoIsActive îți spune că sesiunea 42 ține pe toată lumea blocată:
KILL 42;
Sesiunea face rollback la tranzacția în curs și se deconectează. Toți cei pe care îi bloca se deblochează. Problemă rezolvată.
Atenție: KILL face rollback la tranzacție. Dacă e o tranzacție mare care rulează de o oră, rollback-ul mai poate dura încă o oră. Verifică sys.dm_exec_requests.percent_complete pentru progresul rollback-ului.
Alternativă: KILL N WITH STATUSONLY; — raportează progresul rollback-ului fără a iniția un alt kill.
Nu te teme de KILL. E răspunsul corect pentru interogări scăpate de sub control, tranzacții înțepenite și sesiuni de la un client mort care nu și-a închis niciodată conexiunea.
Cele trei tipuri de sesiuni „zombie” pe care le omori regulat
- Sesiuni
sleepingcu tranzacții deschise. Cineva a pornit un BEGIN TRAN în SSMS, a plecat la prânz. Conexiunea doarme, dar lock-urile sunt ținute. Omoar-o. - Sesiuni
suspendedcare așteaptă lock pentru totdeauna. Cauza e sesiunea care le blochează;sp_WhoIsActive @find_block_leaders = 1arată liderul. Omoară-l pe lider. - Procese
backgroundcare fac lucruri ciudate. Rar. De obicei semnul unei probleme mai adânci. Nu omorî fără discriminare; unele dintre ele sunt fire de execuție interne ale SQL Server.
Bune practici de monitorizare
sp_WhoIsActivela fiecare 30–60 de secunde, logat într-un tabel. Rotește log-ul (păstrează 7 zile). Una dintre mișcările de monitorizare cu cel mai mare impact pe care o poți face.- Alertă pe „sesiuni blocate de > N secunde”. Rulează
sp_WhoIsActive @find_block_leaders = 1din verificarea de alertă; dacă e un block leader și victima a așteptat > 30 de secunde, dă ping celui de gardă. - Pune pe grafic CPU / wait stats din
sys.dm_os_ring_buffersca să ai vizibilitate pe săptămâni, nu doar pe acum.
Rulează asta pe propria mașină
-- 1. Instalează sp_WhoIsActive de pe whoisactive.com
-- 2. Instalează First Responder Kit pentru sp_BlitzFirst
-- 3. Rulează o interogare care durează ceva, într-o sesiune:
BEGIN TRAN;
UPDATE Sales.Customer SET Name = Name + N' (updating)' WHERE CustomerId = 1;
-- Nu face commit. Lasă această sesiune deschisă.
-- 4. În altă sesiune:
EXEC sp_WhoIsActive @find_block_leaders = 1, @get_plans = 1;
-- 5. Vezi starea curentă a waits-urilor
EXEC sp_BlitzFirst;
-- 6. Întoarce-te la sesiunea 1 și fă commit (sau rollback)
COMMIT;
Într-o urgență n-ai ocazia să citești o lecție mai întâi. Exersează aceste unelte pe timp de pace. Memoria musculară e ce te salvează la 3 dimineața.
Următoarea, lecția finală a cursului: un health check de SQL Server în 30 de minute — checklist-ul ordonat pe care îl rulezi pe un server pe care nu l-ai mai văzut. Punând împreună tot din lecțiile 21 până la 40.