web-dev-qa-db-fra.com

Comment les temps d'attente peuvent-ils être supérieurs au temps d'horloge?

Lorsque je suis le suivi des attentes avec sp_BlitzFirst, j'obtiens ce détail:

<?ClickToSeeDetails -- 
For 20 seconds over the last 5 seconds, SQL Server was waiting on this 
particular bottleneck.


 -- ?>

Doit-on lire "20 fois au cours des 5 dernières secondes?" La conclusion était CLR_SEMAPHORE.

15
Robert Rice

Non - les statistiques d'attente peuvent (et plus souvent qu'autrement) totaliser plus que le temps physique passé pour le serveur lui-même.

Imaginez une situation où 2 threads séparés passent la même seconde à attendre une ressource - vous auriez 2 secondes de temps d'attente pour 1 seconde de temps d'horloge.

Chaque thread a ses propres attentes - le message vous indique que 20 secondes de temps d'attente pour cette ressource particulière se sont produites au cours des 5 dernières secondes de l'horloge.

Ou, pour le dire autrement, chaque cœur peut exécuter plusieurs requêtes en même temps, et plusieurs cœurs peuvent s'ajouter à encore plus d'attentes. C'est-à-dire que l'unité est vraiment filetée · secondes, pas secondes.

24
George.Palacios

Il pourrait également être utile de travailler sur un exemple. Considérez les trois états les plus courants pour un travailleur :

RUNNING = Worker s'exécute actuellement de manière non préventive ou préventive.

RUNNABLE = Le travailleur est prêt à s'exécuter sur le planificateur.

SUSPENDED = Le travailleur est actuellement suspendu, en attente d'un événement pour lui envoyer un signal.

Les travailleurs dont l'état est RUNNING peuvent générer un temps d'attente. Par exemple, si le travailleur doit exécuter du code dans le système d'exploitation plutôt que dans SQLOS, il peut entrer une attente préemptive ou externe. Pendant ce temps, il exécutera du code sur son processeur associé, mais générera toujours du temps d'attente.

Les travailleurs avec un état de RUNNABLE peuvent générer un temps d'attente (pour autant que je sache, ils le font toujours). Si le travailleur a été informé qu'une ressource était disponible, il peut accumuler le temps d'attente du signal en fonction de la dernière attente. Si le travailleur a épuisé son quantum précédent de 4 ms, il peut alors accumuler SOS_SCHEDULER_YIELD temps d'attente.

Les travailleurs dont l'état est SUSPENDED peuvent générer un temps d'attente. Considérons un travailleur qui attend un verrou. Il générera un temps d'attente jusqu'à ce qu'il soit signalé que la ressource de verrouillage dont il a besoin est disponible. Certains travailleurs suspendus ne génèrent pas de temps d'attente, y compris ceux qui ne sont pas associés à une tâche.

Mon bureau a quatre cœurs logiques, donc le nombre maximal de travailleurs par défaut est 512 . C'est presque certainement impossible, mais sur cette machine, je pourrais théoriquement générer 512 secondes de temps d'attente par seconde si je réussissais à faire en sorte que chaque travailleur attende quelque chose à la fois. Au fur et à mesure que le nombre de noyaux/travailleurs augmente, ce nombre peut devenir encore plus élevé.

Vous pouvez voir plus d'une seconde d'attente par seconde même si vous n'exécutez aucune requête sur SQL Server. Sur ma machine, la requête suivante semble générer entre 9 et 14 lignes:

SELECT [state], last_wait_type, wait_started_ms_ticks
FROM sys.dm_os_workers
WHERE [state] IN ('SUSPENDED', 'RUNNABLE')
AND task_address IS NOT NULL
AND wait_started_ms_ticks <> 0
AND wait_started_ms_ticks >= start_quantum;

Je peux prendre un instantané du temps d'attente total depuis le dernier redémarrage du serveur et le comparer à un nouveau total après avoir attendu dix secondes:

DECLARE @start_wait_time_ms BIGINT;

SELECT @start_wait_time_ms = SUM(wait_time_ms)
FROM sys.dm_os_wait_stats
WHERE wait_type <> 'WAITFOR';

WAITFOR DELAY '00:00:10';

SELECT SUM(wait_time_ms) - @start_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type <> 'WAITFOR';

Parfois, les mathématiques fonctionnent. La dernière fois que je l'ai exécuté, le delta était de 101339 ms. En d'autres termes, j'ai eu plus de 10 secondes d'attente par seconde rien que pour les tâches système.

8
Joe Obbish