Nel 2014, ho iniziato una serie di post sul blog qui per parlare di tipi di attesa specifici e cosa fanno e cosa non significano. Questo mi ha dato l'idea di creare le librerie wait and latches che mantengo (ne parleremo più avanti).
Se stai leggendo questo e stai pensando "di cosa sta parlando?" allora questo post è per te. Ti presenterò le statistiche di attesa e spiegherò quanto sono fondamentali per la risoluzione dei problemi delle prestazioni del carico di lavoro in SQL Server.
Programmazione
L'esecuzione del codice interno di SQL Server avviene tramite un meccanismo chiamato threads . Ogni thread può eseguire codice SQL Server e più thread si coordinano insieme quando una query viene eseguita in parallelo. Questi thread vengono creati all'avvio di SQL Server, a seconda del numero di core del processore disponibili per SQL Server da utilizzare.
I thread vengono inseriti in un scheduler all'avvio di una query, con uno scheduler per core del processore, e non uscire da tale scheduler fino al termine della query. Uno scheduler ha tre "parti" di base:
- Il processore , che ha esattamente un thread in esecuzione di codice.
- La lista dei camerieri , che ha tutti i thread che sono sostanzialmente bloccati, in attesa che una particolare risorsa diventi disponibile.
- La coda eseguibile , che ha tutti i thread che possono essere eseguiti ma sono in attesa di entrare nel processore.
I thread passano dallo stato 1 a 2 a 3 a 1, in continuazione fino al termine della query.
Aspetta
Dal nostro punto di vista, la parte più interessante della pianificazione è quando un thread deve attendere una risorsa prima di poter continuare. Alcuni esempi di questo sono:
- Un thread deve leggere una pagina e la pagina non è in memoria, quindi il thread emette un I/O fisico asincrono e quindi deve attendere, spento il processore, fino al completamento dell'I/O.
- Un thread deve acquisire un blocco di condivisione su una riga per leggerlo, ma un altro thread contiene già un blocco esclusivo in conflitto mentre aggiorna la riga.
Quando un thread rileva la necessità di una risorsa che non può ottenere, non ha altra scelta che fermarsi e attendere che la risorsa diventi disponibile (il meccanismo per il modo in cui il thread viene notificato sulla disponibilità delle risorse esula dall'ambito di questo articolo). Quando ciò accade, SQL Server prende nota del motivo per cui il thread deve attendere e questo viene chiamato tipo di attesa . Alcuni esempi di questo sono:
- Quando un thread è in attesa che una pagina venga letta in memoria per poterla leggere, il tipo di attesa è PAGEIOLATCH_SH (se il thread è in attesa di una pagina che cambierà, il tipo di attesa è PAGEIOLATCH_EX ).
- Quando un thread è in attesa di un blocco di condivisione su una riga, il tipo di attesa è LCK_M_S (blocco-modalità-condivisione)
SQL Server tiene traccia anche del tempo di attesa del thread. Questo è chiamato tempo di attesa della risorsa , e di solito è noto solo come tempo di attesa .
Statistiche di attesa
L'insieme generale di metriche di quanti thread hanno atteso per quali risorse e per quanto tempo in media è chiamato statistiche di attesa . Queste informazioni sono estremamente utili per la risoluzione dei problemi delle prestazioni del carico di lavoro, poiché puoi facilmente vedere dove potrebbero essere i colli di bottiglia delle prestazioni.
L'idea di base è che SQL Server abbia le informazioni sul motivo per cui i thread devono fermarsi e attendere e cosa stanno aspettando. Quindi, invece di dover indovinare da dove iniziare la risoluzione dei problemi, un'analisi attenta delle statistiche di attesa di solito può indicarti una direzione da prendere.
Ad esempio, se la maggior parte delle attese sul server sono PAGEIOLATCH_SH , ciò potrebbe indicare che la memoria sul server è insufficiente o che ci sono query che eseguono scansioni di tabelle di grandi dimensioni invece di utilizzare indici non cluster, o che c'è un problema con il sottosistema di I/O sottostante o una serie di altri motivi.
Esistono numerosi tipi di attesa, ma la maggior parte di essi non si presenta molto spesso, quindi c'è un set di base che vedrai più e più volte sui tuoi server. Capire cosa significano e come investigarli è fondamentale in modo da non soccombere a ciò che io chiamo "regolazione delle prestazioni istintive" e sprecare tempo e fatica cercando di risolvere un problema che in realtà non è un problema. Ho scritto una serie di post sul blog qui che approfondiscono i dettagli lì, e Aaron Bertrand ha anche scritto un post di riepilogo delle prime 10 statistiche di attesa l'anno scorso.
Tracciamento delle attese
Esistono diversi modi per monitorare le attese. Il più semplice è guardare quali attese si stanno verificando sul server in questo momento, utilizzando uno script che esamina sys.dm_os_waiting_tasks DMV. Puoi trovare uno script per farlo qui e che ha URL generati automaticamente nella libreria di attesa.
Un altro modo è guardare le statistiche di attesa aggregate per l'intero server, con uno script che esamina sys.dm_os_wait_stats DMV. Puoi trovare uno script per farlo qui e che ha URL generati automaticamente nella libreria di attesa. Tuttavia, devi stare attento con quel metodo, poiché mostrerà tutte le attese che si sono verificate dall'avvio del server. Un modo migliore è tenere traccia delle attese su piccoli intervalli, diciamo mezz'ora, e uno script per farlo è qui.
Puoi anche ottenere statistiche sull'attesa usando il componente aggiuntivo Server Reports per il nuovo strumento Azure Data Studio e usando Query Store da SQL Server 2017 in poi.
Ricorda, devi ancora capire cosa significano i tipi di attesa una volta raccolte le metriche.
Aspetta Risorse
Per aiutare con questo, e poiché Microsoft non ha documentazione su come interpretare le statistiche di attesa, nel 2016 ho rilasciato una libreria dei tipi di attesa, con i dettagli di centinaia di tipi di attesa comuni e come risolverli. Puoi accedere alla libreria su https://www.SQLskills.com/help/waits. E poi, nel 2017, SentryOne ha creato un sistema automatizzato per fornire un'infografica per ogni pagina della libreria che puoi utilizzare rapidamente per vedere se il tipo di attesa che ti interessa è davvero comune o meno (vedi questo post per i dettagli) . Di seguito è riportato un esempio di infografica per PAGEIOLATCH_SH tipo di attesa:
Sull'asse orizzontale c'è una scala (commutabile tra lineare e logaritmica) di quale percentuale di istanze (monitorate in remoto da SentryOne) hanno subito questa attesa nel mese di calendario precedente e sull'asse verticale c'è la percentuale di tempo che quelle istanze che hanno sperimentato quella wait aveva effettivamente un thread in attesa di quel tipo di attesa.
Un'altra risorsa per aiutarti a capire le attese è un corso di formazione online che ho registrato per Pluralsight – vedi qui.
Per lo meno, dovresti leggere i vari post del blog nelle sezioni Wait Statistics e Tracking Waits sopra.
Tracciamento delle attese utilizzando gli strumenti SentryOne
SQL Sentry tiene traccia delle attese a livello di istanza automaticamente nel tempo, in modo da non dover cogliere le attese elevate "in atto". Qualcuno si è lamentato di un sistema lento ieri pomeriggio o di un rapporto scaduto martedì scorso? Nessun problema. Puoi analizzare tutte le attese in qualsiasi momento o in un intervallo e correlarle con varie altre metriche delle prestazioni raccolte in quel momento, che si tratti di altre tendenze sulla dashboard, come attività di backup o I/O del database, passando a tutte i comandi SQL principali in esecuzione nella stessa finestra, che esaminano i blocchi di lunga durata o utilizzano le linee di base per confrontare il profilo delle attese con altri periodi.
Puoi persino personalizzare le attese raccolte o meno, modificare le categorie presentate visivamente e creare avvisi e/o risposte intelligenti a scenari di attesa specifici. Molti dei nostri clienti utilizzano SQL Sentry per concentrarsi su problemi di prestazioni reali relativi alle attese, poiché consente loro di ignorare gran parte del rumore che è solo la normale attività dei thread di SQL Server.
Riepilogo
Come puoi vedere dalle informazioni sopra, le attese si verificano sempre in SQL Server, perché è proprio così che funzionano la pianificazione dei thread e i sistemi multi-thread. Sono uno degli strumenti più potenti nella tua cassetta degli strumenti per la risoluzione dei problemi, quindi se non li stai già utilizzando, ora è il momento di iniziare. La curva di apprendimento è breve e ripida:una volta che avrai eseguito le varie query e strumenti un paio di volte, ti ci occuperai rapidamente, quindi è il caso di leggere le guide per le attese che stai vedendo e determinare se sono un problema di no.
Buona risoluzione dei problemi!