Come tenere traccia dei blocchi che si verificano per meno di un secondo: SQL Server


14

Sto cercando di risolvere un problema di blocco che si verifica per meno di un secondo. L'applicazione OLTP è molto sensibile e deve avere un tempo di risposta inferiore a 200 ms per alcune transazioni secondo lo SLA concordato. Abbiamo riscontrato alcuni problemi di escalation dei blocchi con la nuova versione del codice che siamo stati in grado di risolvere riducendo le dimensioni del batch negli aggiornamenti. Anche con le piccole dimensioni del batch, sospettiamo che il nuovo sp stia bloccando le stesse righe che le transazioni OLTP stanno aggiornando.

Devo trovare la sessione che viene bloccata e la risorsa su cui sta aspettando. Secondo la mia comprensione, la "soglia di processo bloccata" può essere impostata per almeno 1 secondo e quindi questo non bloccherà il blocco.

Sto sperimentando wait_info e wait_completed x events.

Esiste un altro modo per rintracciarlo. Grazie


stessa domanda su così da stesso utente: stackoverflow.com/questions/38407021/...
TheGameiswar

Risposte:


10

Dato che sei particolarmente interessato al blocco piuttosto che alle attese generali, l' locks_lock_waitsevento esteso sembra più adatto.

Con un filtro attivo increment >= 200

CREATE EVENT SESSION [locks_lock_waits] ON SERVER 
ADD EVENT sqlserver.locks_lock_waits(
        ACTION(sqlserver.sql_text)
            WHERE  ( [sqlserver].[is_system] = 0
                     AND [increment] >= 200
                     AND [counter] <= 1000 ) 
    )
ADD TARGET package0.ring_buffer;

GO

ALTER EVENT SESSION [locks_lock_waits]  
ON SERVER  STATE = start;  

Quanto sopra raccoglie le istruzioni in attesa sui blocchi per la soglia di tempo ma non fornisce la risorsa di blocco specifica.

Non ho mai usato questo evento e non ho idea di quanto sovraccarico causerebbe questa sessione sul tuo server di produzione.

Ho trovato questo video sull'argomento. Ciò raccomanda vivamente di filtrare counterper ridurre il numero di eventi raccolti e l'ho fatto sopra.

Menziona anche un vecchio comando non documentato legacy

dbcc lock(StallReportThreshold, 200) -- 200 is threshold in ms

Che (se il flag di traccia 3605 è abilitato) scarica informazioni limitate come quelle seguenti nel log degli errori di SQL Server.

Il processo 53 ha atteso 6844 ms per il blocco S su RID: 2: 1: 120: 2 risultato: OKWAIT

Ne parlo solo di sfuggita, poiché eventi estesi sarebbero chiaramente preferibili in ogni caso poiché sono documentati e molto più potenti.


Ho testato locks_lock_waits e, come hai detto, non ha le informazioni sulla risorsa. Ma non sapevo che l'incremento fosse il tempo. Buone informazioni blocco dbcc, sembra fantastico. Sai per quanto tempo queste informazioni sono disponibili prima che possano essere scaricate nel registro degli errori.
jesijesi,

Mi dispiace, non mi sono chiarito. Stavo chiedendo quanto tempo abbiamo fino a quando non eseguiamo il comando dbcc lock. Ad esempio il blocco avviene e se eseguo il blocco dbcc dopo un'ora, riceviamo ancora le informazioni?
jesijesi,

@jesijesi - Oggi non ne avevo mai sentito parlare. Non ho ulteriori informazioni al riguardo. Non conosco nemmeno i parametri da passare per disabilitarlo. Ma esegui per dbcc lock(StallReportThreshold, 200) primo e genera le informazioni una volta superata la soglia fintanto che il flag di traccia 3605 è abilitato. SQL Server non raccoglie queste informazioni nel caso in cui sia possibile eseguirle in un secondo momento.
Martin Smith,

2
Grazie. semplicemente aggiungendo un collegamento che ha una funzione utile per convertire i valori resource_0,1,2 in xevents. sqlnotes.info/2011/10/24/…
jesijesi il

5

Se sei interessato a bloccare, ci sono diversi eventi estesi disponibili:

lock_acquired
lock_released
lock_escalation

I primi due eventi hanno una durationcolonna in (microsecondi) che puoi filtrare per le tue soglie. Hanno anche resource_descriptionun'azione che ti darà alcuni dettagli sulle risorse coinvolte.

L' lock_escalationevento ha anche statementun'azione che è possibile aggiungere per raccogliere l'istruzione T-SQL che ha attivato l'escalation del blocco. Ha anche escalation_cause. Ecco una sessione di esempio:

CREATE EVENT SESSION [locking] ON SERVER 
ADD EVENT sqlserver.lock_acquired( SET collect_resource_description = (1) ),
ADD EVENT sqlserver.lock_escalation( SET collect_statement = (1) ),
ADD EVENT sqlserver.lock_released( SET collect_resource_description = (1) )
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO

Ho il sospetto che ci sia probabilmente un motivo per cui non puoi impostare la soglia del rapporto di processo bloccato su meno di un secondo: il blocco è perfettamente normale in un RDBMS - il motore di database deve bloccare le risorse per proteggerle. Anche se non esiste una definizione ufficiale su quando il blocco diventa un blocco, il blocco del ticchettio su un secondo secondario mi sembra normale.


1
il blocco diventa bloccato non appena a qualcun altro viene negato l'accesso alla risorsa e deve attendere a causa del blocco.
Martin Smith,

Grazie, sto programmando di usare lock_acquired con il campo della durata.
jesijesi,

In bocca al lupo. Come in SQL Server 2014, è possibile utilizzare le tabelle OLTP in memoria con i processi memorizzati compilati in modo nativo offrono un'opzione senza latch ad alte prestazioni. Potresti anche guardare l'isolamento dell'istantanea.
wBob,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.