Diese Instanz hostet die SharePoint 2007-Datenbanken (SP). Wir haben zahlreiche SELECT / INSERT-Deadlocks für eine stark genutzte Tabelle in der SP-Inhaltsdatenbank festgestellt. Ich habe die beteiligten Ressourcen eingegrenzt. Beide Prozesse erfordern Sperren für den nicht gruppierten Index.
Das INSERT benötigt eine IX-Sperre für die SELECT-Ressource und das SELECT benötigt eine S-Sperre für die INSERT-Ressource. Das Deadlock-Diagramm zeigt und drei Ressourcen, 1.) zwei aus dem SELECT (Producer / Consumer Parallel Threads) und 2.) das INSERT.
Ich habe das Deadlock-Diagramm für Ihre Überprüfung angehängt. Da es sich um Microsoft-Code- und -Tabellenstrukturen handelt, können wir keine Änderungen vornehmen.
Ich habe jedoch auf der MSFT SP-Site gelesen, dass empfohlen wird, die Konfigurationsoption auf MAXDOP-Instanzebene auf 1 zu setzen. Da diese Instanz von vielen anderen Datenbanken / Anwendungen gemeinsam genutzt wird, kann diese Einstellung nicht deaktiviert werden.
Daher habe ich beschlossen, zu verhindern, dass diese SELECT-Anweisungen parallel verlaufen. Ich weiß, dass dies keine Lösung ist, sondern eher eine vorübergehende Änderung, um bei der Fehlerbehebung zu helfen. Daher habe ich den „Kostenschwellenwert für Parallelität“ von 25 auf 40 erhöht, obwohl sich die Arbeitslast nicht geändert hat (SELECT / INSERT tritt häufig auf), sind die Deadlocks verschwunden. Meine Frage ist warum?
SPID 356 INSERT verfügt über eine IX-Sperre für eine Seite, die zum nicht gruppierten Index gehört.
SPID 690 SELECT Die Ausführungs-ID 0 verfügt über eine S-Sperre für eine Seite, die zu demselben nicht gruppierten Index gehört
Jetzt
SPID 356 möchte eine IX-Sperre für die SPID 690-Ressource, kann sie jedoch nicht erhalten, da SPID 356 durch die SPID 690-Ausführungs-ID 0 blockiert wird. S-Sperre
SPID 690 Die Ausführungs-ID 1 möchte eine S-Sperre für die SPID 356-Ressource, kann sie jedoch nicht erhalten, da die SPID 690-Ausführungs-ID 1 wird von SPID 356 blockiert und jetzt haben wir unseren Deadlock.
Der Ausführungsplan befindet sich auf meinem SkyDrive
Vollständige Deadlock-Details finden Sie hier
Wenn mir jemand helfen kann zu verstehen, warum ich es wirklich schätzen würde.
EventReceivers-Tabelle.
ID uniqueidentifier no 16
Name 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 nein 512
Daten nvarchar nein 512
Filter nvarchar nein 512
SourceId tContentTypeId nein 512
SourceType int no 4
Credential int no 4
ContextType varbinary no 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 nicht gruppierten sich auf PRIMARY SITEID, ContextCollectionId
NONCLUSTERED EventReceivers_ByContextObjectId befindet sich auf PRIMARY SITEID, ContextObjectId
EventReceivers_ById Nonclustered, einzigartig gelegen auf PRIMARY SITEID, Id
EventReceivers_ByTarget gruppierten, einzigartig gelegen auf PRIMARY SITEID, webid, HostId, Unterkuntstyp, Typ, ContextCollectionId, ContextObjectId, ContextId, ContextType, ContextEventType, SequenceNumber, Assembly, Klasse
EventReceivers_IdUnique nicht gruppierter, eindeutiger, eindeutiger Schlüssel in der PRIMARY-ID
quelle
proc_InsertEventReceiver
undproc_InsertContextEventReceiver
tun, was wir in der XDL nicht sehen können? Um die Parallelität zu verringern, sollten Sie diese Anweisung nicht direkt (mit MAXDOP 1) beeinflussen, anstatt mit serverweiten Einstellungen zu arbeiten.Antworten:
Auf den ersten Blick sieht dies wie ein klassischer Lookup-Deadlock aus . Die wesentlichen Bestandteile für dieses Deadlock-Muster sind:
SELECT
Abfrage, die einen nicht abdeckenden nicht gruppierten Index mit einer Schlüsselsuche verwendetINSERT
Abfrage, die den Clustered-Index und dann den Nonclustered-Index ändertDer
SELECT
greift zuerst auf den nicht gruppierten Index und dann auf den gruppierten Index zu. DerINSERT
Zugriff zuerst auf den Clustered-Index, dann auf den Nonclustered-Index. Der Zugriff auf dieselben Ressourcen in einer anderen Reihenfolge, um inkompatible Sperren zu erhalten, ist natürlich eine großartige Möglichkeit, einen Deadlock zu erreichen.In diesem Fall
SELECT
lautet die Abfrage:... und die
INSERT
Abfrage lautet:Beachten Sie die grün hervorgehobene Wartung von nicht gruppierten Indizes.
Wir müssten die serielle Version des
SELECT
Plans sehen, falls sie sich stark von der parallelen Version unterscheidet. Wie Jonathan Kehayias in seinem Handbuch zur Behandlung von Deadlocks feststellt , ist dieses spezielle Deadlock-Muster sehr empfindlich gegenüber dem Timing und den Details der Implementierung der internen Abfrageausführung. Diese Art von Deadlock kommt und geht oft ohne offensichtlichen externen Grund.Angesichts des Zugriffs auf das betreffende System und geeigneter Berechtigungen können wir sicher genau herausfinden, warum der Deadlock beim parallelen Plan auftritt, nicht jedoch bei der seriellen (unter Annahme derselben allgemeinen Form). Potenzielle Untersuchungslinien umfassen für optimierte verschachtelten Schleifen überprüft und / oder Prefetching - von denen beide intern kann die Isolationsstufe eskalieren zu
REPEATABLE READ
für die Dauer der Anweisung. Es ist auch möglich, dass eine Funktion der Zuweisung des parallelen Index-Suchbereichs zu dem Problem beiträgt. Wenn der Serienplan verfügbar wird, werde ich möglicherweise einige Zeit damit verbringen, die Details weiter zu untersuchen, da dies möglicherweise interessant ist.Die übliche Lösung für diese Art von Deadlocking besteht darin, den Index abzudecken, obwohl die Anzahl der Spalten in diesem Fall dies möglicherweise unpraktisch macht (und außerdem sollten wir uns in SharePoint nicht mit solchen Dingen herumschlagen, wurde mir gesagt). Letztendlich gibt es die Empfehlung für Nur-Serien-Pläne bei der Verwendung von SharePoint aus einem bestimmten Grund (wenn auch nicht unbedingt gut, wenn es darauf ankommt). Wenn die Änderung der Kostenschwelle für Parallelität das Problem im Moment behebt, ist dies gut. Längerfristig würde ich wahrscheinlich versuchen, die Workloads zu trennen, möglicherweise mithilfe von Resource Governor, damit interne SharePoint-Abfragen das gewünschte
MAXDOP 1
Verhalten erhalten und die andere Anwendung Parallelität verwenden kann.Die Frage des Austauschs in der Sackgasse scheint mir ein roter Hering zu sein; einfach eine Folge der unabhängigen Threads, die Ressourcen besitzen, die technisch im Baum erscheinen müssen. Ich kann nichts sehen, was darauf hindeutet, dass die Börsen selbst direkt zum Deadlocking-Problem beitragen.
quelle
Wenn dies ein klassischer Such-Deadlock war , enthält die Ressourcenliste sowohl den Clustered Index als auch den Non-Clustered Index. Normalerweise hält der SELECT eine SHARED-Sperre für den NC-Index und wartet auf eine SHARED-Sperre für das CI, während der INSERT eine EXCLUSIVE-Sperre für das CI erhält und auf eine EXCLUSIVE-Sperre für den NC wartet. In der Ressourcenliste in der Deadlock-XML werden in diesem Fall beide Objekte aufgelistet.
Da das Deadlock-Diagramm nur den NC-Index enthält, können wir diese Option ausschließen.
Wenn dies aufgrund von Nested Loop Join mit UNORDERED PREFETCH eine Dead Lock war , gibt der Ausführungsplan an, ob der UNORDERED PREFETCH-Algorithmus verwendet wird, was auch hier nicht der Fall ist (siehe Update unten).
Das lässt uns annehmen, dass dies aufgrund des Parallelplans ein Deadlock ist.
Das Deadlock-Diagramm wird nicht richtig gerendert. Wenn Sie sich jedoch das Deadlock-XML ansehen, sehen Sie, dass zwei Threads aus der SELECT-Anweisung (SPID 690) am Deadlock beteiligt sind. Der Consumer-Thread hält eine SHARED-Sperre auf SEITE 1219645 und wartet auf den Produzenten auf Port801f8ed0 (e_waitPipeGetRow). Der Producer-Thread wartet auf eine gemeinsame Sperre auf SEITE 1155940.
Die INSERT-Anweisung hält eine IX-Sperre auf SEITE 1155940 und wartet auf eine IX-Sperre auf SEITE 1219645, was zu einem Deadlock führt.
Ich glaube, dass ein Deadlock verhindert wird, wenn ein serieller Plan für die SELECT-Anweisung verwendet wird, da zu keinem Zeitpunkt eine SHARED-Sperre für mehr als eine Seite erforderlich ist. Ich denke auch, dass der serielle Plan fast der gleiche sein wird wie der parallele Plan (ohne Parallelitätsoperator).
[AKTUALISIERT basierend auf Pauls Kommentar]
Anscheinend verwendet der Plan einen OPTIMIZED Nested Loop-Algorithmus
Dies erklärt, warum die SHARED-Sperren bis zum Ende der Anweisung gehalten werden. WIEDERHOLBARES LESEN in Kombination mit einem parallelen Plan ist anfälliger für Deadlocks als ein serieller Plan, da der parallele Plan Sperren aus verschiedenen Bereichen eines Index erfassen und beibehalten kann, während der serielle Plan Sperren auf sequentiellere Weise erfasst.
quelle