Cette instance héberge les bases de données SharePoint 2007 (SP). Nous avons rencontré de nombreux blocages SELECT / INSERT sur une table fortement utilisée dans la base de données de contenu SP. J'ai réduit les ressources impliquées, les deux processus nécessitent des verrous sur l'index non cluster.
L'INSERT a besoin d'un verrou IX sur la ressource SELECT et le SELECT a besoin d'un verrou S sur la ressource INSERT. Le graphique de blocage représente et trois ressources, 1.) deux du SELECT (threads parallèles producteur / consommateur), et 2.) l'INSERT.
J'ai joint le graphique de blocage pour votre examen. Étant donné qu'il s'agit de structures de code et de table Microsoft, nous ne pouvons apporter aucune modification.
Cependant, j'ai lu, sur le site MSFT SP, qu'ils recommandent de définir l'option de configuration de niveau d'instance MAXDOP sur 1. Puisque cette instance est partagée entre de nombreuses autres bases de données / applications, ce paramètre ne peut pas être désactivé.
Par conséquent, j'ai décidé d'essayer d'empêcher ces instructions SELECT de se mettre en parallèle. Je sais que ce n'est pas une solution mais plutôt une modification temporaire pour aider au dépannage. Par conséquent, j'ai augmenté le «seuil de coût pour le parallélisme» de notre standard 25 à 40 en procédant ainsi, même si la charge de travail n'a pas changé (SELECT / INSERT se produisant fréquemment), les blocages ont disparu. Ma question est pourquoi?
SPID 356 INSERT a un verrou IX sur une page appartenant à l'index non clusterisé
SPID 690 SELECT ID d'exécution 0 a un verrou S sur une page appartenant au même index non clusterisé
Maintenant
Le SPID 356 souhaite un verrou IX sur la ressource SPID 690 mais ne peut pas le contenir car le SPID 356 est bloqué par l'ID d'exécution SPID 690 0 Verrou S
L'ID d'exécution SPID 690 1 veut un verrou S sur la ressource SPID 356 mais ne peut pas l'obtenir car l'ID d'exécution SPID 690 1 est bloqué par le SPID 356 et nous avons maintenant notre blocage.
Le plan d'exécution se trouve sur mon SkyDrive
Les détails complets de l'impasse peuvent être trouvés ici
Si quelqu'un peut m'aider à comprendre pourquoi je l'apprécierais vraiment.
Table EventReceivers.
Id uniqueidentifier no 16
Nom nvarchar no 512
SiteId uniqueidentifier no 16
WebId uniqueidentifier no 16
HostId uniqueidentifier no 16
HostType int no 4
ItemId int no 4
DirName nvarchar no 512
LeafName nvarchar no 256
Type int no 4
SequenceNumber int no 4
Assembly nvarchar no 512
Class nvarchar non 512
Data nvarchar non 512
Filter nvarchar non 512
SourceId tContentTypeId non 512
SourceType int non 4
Credential int non 4
ContextType varbinary non 16
ContextEventType varbinary no 16
ContextId varbinary no 16
ContextObjectId varbinary no 16
ContextCollectionId varbinary no 16
index_name index_description index_keys
EventReceivers_ByContextCollectionId nonclustered situé sur PRIMAIRES SiteId, ContextCollectionId
EventReceivers_ByContextObjectId NONCLUSTERED situé sur PRIMAIRES SiteId, ContextObjectId
EventReceivers_ById NONCLUSTERED, unique situé sur PRIMAIRES SiteId, Id
EventReceivers_ByTarget en clusters, situé unique sur PRIMAIRES SiteId, webid, HostId, HostType, Type, ContextCollectionId, ContextObjectId, ContextId, ContextType, ContextEventType, SequenceNumber, Assembly, Class
EventReceivers_IdUnique nonclustered, unique, clé unique située sur l'ID PRIMARY
la source
proc_InsertEventReceiver
etproc_InsertContextEventReceiver
que nous ne pouvons pas voir dans le XDL? Aussi pour réduire le parallélisme, pourquoi ne pas avoir un impact direct sur ces instructions (en utilisant MAXDOP 1) au lieu de jouer avec les paramètres à l'échelle du serveur?Réponses:
À première vue, cela ressemble à une impasse de recherche classique . Les ingrédients essentiels de ce modèle de blocage sont:
SELECT
requête qui utilise un index non cluster non couvrant avec une recherche de cléINSERT
requête qui modifie l'index cluster, puis l'index non clusterLe
SELECT
accède d'abord à l'index non cluster, puis à l'index cluster. L'INSERT
accès l'index ordonné en clusters, puis l'index non cluster. Accéder aux mêmes ressources dans un ordre différent en acquérant des verrous incompatibles est un excellent moyen de «réaliser» un blocage, bien sûr.Dans ce cas, la
SELECT
requête est:... et la
INSERT
requête est:Remarquez la maintenance des index non cluster en surbrillance verte.
Nous aurions besoin de voir la version série du
SELECT
plan au cas où elle serait très différente de la version parallèle, mais comme Jonathan Kehayias le note dans son guide sur la gestion des blocages , ce modèle de blocage particulier est très sensible au timing et aux détails d'implémentation de l'exécution des requêtes internes. Ce type d'interblocage va et vient souvent sans raison extérieure évidente.Compte tenu de l'accès au système concerné et des autorisations appropriées, je suis certain que nous pourrions éventuellement déterminer exactement pourquoi le blocage se produit avec le plan parallèle mais pas le sériel (en supposant la même forme générale). Lignes potentielles d'enquête comprennent la vérification des boucles imbriquées optimisées et / ou préchargement - qui en interne peuvent tous deux grimper le niveau d'isolement à
REPEATABLE READ
la durée de l'instruction. Il est également possible que certaines caractéristiques de l'attribution de plage de recherche d'index parallèle contribuent au problème. Si le plan de série devient disponible, je pourrais passer un peu de temps à approfondir les détails, car il est potentiellement intéressant.La solution habituelle pour ce type de blocage est de rendre l'index couvrant, bien que le nombre de colonnes dans ce cas puisse rendre cela impossible (et d'ailleurs, nous ne sommes pas censés gâcher de telles choses sur SharePoint, me dit-on). En fin de compte, la recommandation de plans de série uniquement lors de l'utilisation de SharePoint est là pour une raison (mais pas nécessairement une bonne, en fin de compte). Si le changement de seuil de coût pour le parallélisme résout le problème pour le moment, c'est bien. À plus long terme, je chercherais probablement à séparer les charges de travail, peut-être en utilisant le gouverneur de ressources afin que les requêtes internes SharePoint obtiennent le
MAXDOP 1
comportement souhaité et que l'autre application puisse utiliser le parallélisme.La question des échanges apparaissant dans la trace de l'impasse me semble un sujet rouge; simplement une conséquence des threads indépendants possédant des ressources qui doivent techniquement apparaître dans l'arborescence. Je ne vois rien suggérer que les échanges eux-mêmes contribuent directement au problème de l'impasse.
la source
S'il s'agissait d'un blocage de recherche classique , la liste des ressources inclura à la fois l'index cluster et l'index non cluster. Typiquement, le SELECT tiendra un verrou PARTAGÉ sur l'index NC et attendra un verrou PARTAGÉ sur le CI, tandis que l'INSERT acquerra un verrou EXCLUSIF sur le CI et attendra un verrou EXCLUSIF sur le NC. La liste des ressources dans le xml de blocage listera ces deux objets dans ce cas.
Étant donné que le graphique de blocage n'implique que l'index NC, nous pouvons exclure cette option.
De plus, s'il s'agissait d'un verrou mort en raison de la jointure en boucle imbriquée avec UNORDERED PREFETCH , le plan d'exécution nous dira si l'algorithme UNORDERED PREFETCH est utilisé, ce qui n'est pas encore le cas ici (voir la mise à jour ci-dessous).
Cela nous laisse supposer qu'il s'agit d'une impasse due au Plan parallèle.
Le graphique de blocage n'est pas rendu correctement, mais si vous regardez le XML de blocage, vous pouvez voir que deux threads de l'instruction SELECT (SPID 690) sont impliqués dans le blocage. Le thread consommateur détient un verrou PARTAGÉ sur la PAGE 1219645 et attend le producteur sur le port801f8ed0 (e_waitPipeGetRow). Le thread producteur attend un verrou partagé sur la PAGE 1155940.
L'instruction INSERT contient un verrou IX sur la PAGE 1155940 et attend un verrou IX sur la PAGE 1219645, entraînant un blocage.
Je crois qu'un blocage sera évité lors de l'utilisation d'un plan de série pour l'instruction SELECT, car à aucun moment il ne faudra un verrou PARTAGÉ sur plus d'une page. Je pense aussi que le plan série sera presque le même que le plan parallèle (sans l'opérateur de parallélisme).
[MISE À JOUR basée sur le commentaire de Paul]
Apparemment, le plan utilise un algorithme de boucle imbriquée OPTIMISÉ
Cela explique pourquoi les verrous PARTAGÉS sont maintenus jusqu'à la fin de la déclaration. REPEATABLE READ combiné avec un plan parallèle est plus vulnérable aux interblocages qu'un plan série car le plan parallèle peut acquérir et conserver des verrous de différentes plages d'un index alors que le plan série acquiert des verrous de manière plus séquentielle.
la source