Besoin de comprendre l'erreur d'exécution de requête parallèle

18

Aujourd'hui, nous avons constaté une dégradation des performances de notre serveur sql de production. Au moment où cela s'est produit, nous avons enregistré plusieurs "The query processor could not start the necessary thread resources for parallel query execution"erreurs. La lecture que j'ai faite suggère que cela a à voir avec le nombre de processeurs à utiliser lors de l'exécution d'une requête complexe. Cependant, lorsque j'ai vérifié pendant la panne, notre CPU Utilization was only at 7%. Y a-t-il autre chose à quoi cela pourrait faire référence que je n'ai pas encore rencontré? Est-ce probablement un coupable de la dégradation des performances ou suis-je à la poursuite d'un hareng rouge?

Mes valeurs sp_configure pour cela sont les suivantes:

name                                minimum maximum config_value run_value
cost threshold for parallelism      0       32767   5            5
Grumeleux
la source
Quelle est la valeur de max degree of parallelismconfiguré et combien de processeurs avez-vous actuellement sur le serveur avec la configuration NUMA? Vous pouvez utiliser à coreinfo.exepartir de sysinternals pour connaître le nombre de processeurs et la configuration NUMA.
Kin Shah
Le degré maximal de parallélisme est défini sur 0
Lumpy
Cela explique pourquoi le serveur sql manque de ressources pour les threads.
Kin Shah
@Kin J'ai 12 processeurs (0 - 11) puis deux processeurs logiques vers la carte des nœuds NUMA: entrées Nœud 0, Nœud 1
Lumpy
@Kin Je pensais que 0 ment que SQL Server gérait le nombre de threads qu'il devait utiliser. Pourquoi cela entraînerait-il la privation de SQL Server pour les ressources de thread?
Lumpy

Réponses:

19

Il y a quelques mois, j'ai fait face à une situation similaire dans laquelle le paramètre MAXDOP était par défaut et une requête de fuite a épuisé tous les threads de travail.

Comme l'a souligné Remus, cela s'appelle la famine du thread de travail .

Un vidage de mémoire sera créé sur votre serveur lorsque cette condition se produira.

Si vous utilisez 2008R2 + SP1 et plus, vous sys.dm_server_memory_dumpsobtiendrez également l'emplacement du fichier de vidage.

Revenons maintenant au problème:

Il y a 1 thread de surveillance du planificateur par nœud NUMA et puisque vous avez 2 nœuds NUMA, il y aura 2 threads de surveillance du planificateur qui sont responsables de la vérification de la santé de tous les planificateurs toutes les 60 secondes pour ce nœud NUMA particulier tout en s'assurant que le planificateur est bloqué ou ne pas.

Chaque fois qu'une nouvelle demande de travail est extraite de la file d'attente de travail des planificateurs, le compteur des processus de travail est incrémenté. Donc, si le planificateur a une demande de travail en file d'attente et n'a pas traité l'une des demandes de travail en 60 secondes, le planificateur est considéré comme bloqué.

En raison d'une requête de fuite ou d'un parallélisme étendu, une condition de threads de travail commence à être épuisée car tous les threads sont occupés par cette requête de fuite unique ou un blocage prolongé excessif et aucun travail ne peut être effectué à moins que ce processus offensant ne soit tué.

Votre meilleur pari est de régler d'abord votre paramètre Max Degree of Parallelism . Par défaut 0 , SQL Server peut utiliser tous les processeurs disponibles pour le traitement parallèle et en épuisant tous les threads de travail.

De nombreuses raisons peuvent conduire à l'épuisement des threads de travail:

  • Longues chaînes de blocage étendues entraînant le manque de threads de travail dans SQL Server
  • Parallélisme étendu conduisant également à l'épuisement des threads de travail
  • Attente prolongée pour tout type de «verrou» - verrous tournants, verrous. Un spinlock orphelin en est un exemple.

Reportez-vous à ma réponse ici qui vous montrera comment vous pouvez calculer la valeur MAXDOP pour votre instance de serveur.

En outre, nous vous recommandons vivement de commencer à collecter des informations sur les statistiques d'attente sur votre instance de serveur de base de données.

Kin Shah
la source
y a-t-il quelque chose qui serait indicatif d'une requête de fuite? Quelque chose que je peux utiliser pour tenter d'identifier les requêtes qui sont à risque de cela?
grumeleux
Vous suggérons de consulter les informations sur les statistiques d'attente pour savoir où cela fait mal . Regardez également sys.dm_os_schedulers-> current_tasks_count, runnable_tasks_count, current_workers_count et active_workers_count ainsi quesys.dm_os_wait_stats etsys.dm_os_waiting_tasks
Kin Shah
10

Il pourrait y avoir plusieurs raisons. Le plus probable est que vous n'aviez plus de travailleurs. Tu vois max_worker_threads. La condition est appelée «stravation des travailleurs». Les travailleurs pourraient être volés par l'un des multiples moyens (dont aucun n'entraînerait une utilisation élevée du processeur, entre autres), comme bloquer de nombreuses demandes ou faire des choses stupides dans CLR (par exemple, des requêtes HTTP).

Le symptôme que vous voyez est la victime du problème, pas la cause. Nous ne pouvons pas recommander une solution sans connaître la cause. Vous devez collecter les compteurs de performances, les DMV et consulter le ERRORLOG pour plus d'informations.

Remus Rusanu
la source
max threads de travail Min = 128, max = 32767, config = 0, run = 0
Lumpy
2
@Lumpy C'est votre configuration max, mais ce n'est pas du tout le nombre maximal de travailleurs. Nous aurions besoin de savoir combien de processeurs votre machine doit calculer.
Thomas Stringer