So reproduzieren Sie "Scan mit NOLOCK konnte aufgrund von Datenverschiebung nicht fortgesetzt werden"


10

Ich erhalte gelegentlich die Meldung "Der Scan konnte NOLOCKaufgrund von Datenverschiebungen nicht fortgesetzt werden " bei einigen großen Jobs, die WITH (NOLOCK)in den ausgewählten Abfragen enthalten sind.

Ich verstehe, dass dies etwas mit dem Versuch zu tun hat, Daten auszuwählen, wenn ein Seitenteil aufgeteilt wurde, der dazu führte, dass die Daten nicht mehr dort waren, wo sie sein sollten - ich gehe davon aus, dass dies in meiner Umgebung geschieht.

Wie würde ich das reproduzieren?

Ich versuche, eine kurzfristige Problemumgehung durchzuführen, um den Fehler abzufangen und es in diesem Fall erneut zu versuchen, aber ich kann ihn nicht testen, wenn ich ihn nicht reproduzieren kann. Gibt es einen einigermaßen zuverlässigen Weg, dies zu verursachen?

In diesem Fall führt die erneute Ausführung der Abfrage zum Erfolg. Daher habe ich keine Bedenken, dass die tatsächlichen Daten oder Datenbanken dauerhaft beschädigt sind. Einige der Tabellen in der Abfrage (zusammen mit ihren Indizes) werden häufig gelöscht, neu erstellt und neu gefüllt, daher gehe ich davon aus, dass dies etwas damit zu tun hat.

Das Entfernen NOLOCKist mein langfristiges Problem. Der Grund dafür NOLOCKwar in erster Linie, dass die Abfragen so schlecht sind, dass sie bei alltäglichen Transaktionen NOLOCKzum Stillstand kamen , ebenso wie ein Pflaster, um die Deadlocks zu stoppen (was funktionierte). Ich brauche also ein Pflaster für ein Pflaster, bis wir eine dauerhafte Lösung finden können.

Wenn ich es mit einer Hello World reproduzieren könnte, würde ich wahrscheinlich planen, das Pflaster in weniger als einer Stunde in den Job zu stecken. Das Entfernen und Ersetzen kann nicht durchgeführt werden NOLOCK, da ich wieder Deadlocks für die App bekomme, die für mich schlimmer sind als ein gelegentlich fehlgeschlagener Job.

Die Isolierung von gelesenen festgeschriebenen Snapshots ist eine gute Möglichkeit. Ich muss mit unserem Datenbankteam zusammenarbeiten, um weitere Details dazu zu erhalten. Ein Teil unseres Problems ist, dass wir keinen SQL Server-Experten haben, der sich mit solchen Dingen befasst, und ich verstehe die Isolationsstufen nicht gut genug, um diese Änderung derzeit vorzunehmen.


1
Haben Sie darüber nachgedacht, NOLOCKdiese Jobs einfach zu entfernen ? 601 sollte Ihre geringste Sorge sein, wenn die Ergebnisse dieser Abfragen korrekt sein sollen . Paul White zeigt ein besonders abschreckendes Beispiel Daten zu lesen , die nicht möglich sein soll , hier .
Aaron Bertrand

3
Sie könnten setzen DEADLOCK_PRIORITYauf LOWin den Jobs, so dass , wenn es Deadlocks sind, werden die Aufträge fehlschlagen, und nicht die Anwendungen. Danach können Sie die Deadlocks untersuchen, herausfinden, warum sie auftreten, und dieses Problem beheben. Es könnte eine sehr einfache Lösung sein, wie das Vertauschen der Reihenfolge zweier Anweisungen. Was auch immer das Problem ist, es NOLOCKist nicht die Lösung . Hören Sie also auf, es zu erzwingen, nur weil es am einfachsten ist.
Aaron Bertrand

@ AaronBertrand Danke, wusste nichts über DEADLOCK_PRIORITY - ich werde das untersuchen. Wir haben versucht, die Deadlocks aufzuspüren, aber diese ereigneten sich zu verschiedenen scheinbar zufälligen Zeiten und nur ein- oder zweimal pro Tag und sind bei Bedarf nie reproduzierbar. Unsere geplanten Jobs führen jede Stunde Zehntausende von Abfragen aus, und unsere App führt Hunderte aus von Abfragen, wenn nur eine Seite geladen oder etwas gespeichert wird, und wir haben nicht herausgefunden, welche Abfrage auf beiden Seiten am Deadlock beteiligt ist. Ich hatte nicht die Absicht, NOLOCK für immer dort zu lassen, weshalb wir nach besseren langfristigen Lösungen suchen.
Wookie23

1
Sie haben erwähnt, dass es Ihnen schwer fällt, die Deadlocks aufzuspüren. Angesichts der Tatsache, dass Sie sich in 2008 R2 befinden, können Sie hier nachsehen : sqlservercentral.com/articles/deadlock/65658 Jonathan Kehayias geht das Abrufen von Deadlock-Informationen aus dem Ringpuffer durch.
Kenneth Fisher

Die Antworten und Kommentare sprechen das zugrunde liegende Problem gut an, aber sind Sie immer noch daran interessiert, einen Weg zu finden, dies als intellektuelle Übung zu reproduzieren?
James L

Antworten:


8

Da eine mögliche "Band-Hilfe" für die NOLOCK-Probleme darin besteht, die Verwendung von NOLOCK zu beenden und mit der READ_COMMITTED_SNAPSHOT-Isolation zu beginnen, möchte ich Sie auf den Blog-Beitrag unter http://www.brentozar.com von Kendra Little verweisen : Implementieren von Snapshot oder Read Committed Snapshot-Isolation in SQL Server: Ein Handbuch .

Kendra bietet mit der Isolationsstufe READ_COMMITTED_SNAPSHOT zahlreiche Details zu Nutzen und Risiken.

  1. Diese Isolationsstufe wird zur Standardisolationsstufe für den Datenbankcode.
  2. Sie müssen nur einen Benutzer in der Datenbank haben, um die Isolationsstufe READ_COMMITTED_SNAPSHOT ändern zu können.
  3. Selbst wenn Sie die READ_COMMITTED_SNAPSHOT-Isolation verwenden, müssen Sie die NOLOCK-Hinweise entfernen, da sie die Standardeinstellung überschreiben.
  4. Einige Ihrer Codes haben möglicherweise Probleme, die behoben werden müssen.

Vor einigen Jahren führten wir READ_COMMITTED_SNAPSHOT Isolation auf einer Datenbank , das wurde stark vom Leiden blockiert . Aber als wir die Isolationsstufe geändert hatten, begannen wir in einigen kritischen Bereichen Deadlocks zu bekommen .

Warum ist das passiert? Da die vorherige Isolationsstufe eine starke Blockierung verursachte, konnte der Code "nie" den Punkt des Deadlocks erreichen. Mit der Isolation READ_COMMITTED_SNAPSHOT können die Abfragen jedoch fortgesetzt werden. Ein gewisser Prozentsatz der nicht mehr wartenden Transaktionen begann jedoch zu blockieren.

Glücklicherweise wurde unser Fall schnell gelöst, indem die Deadlock-Punkte ermittelt und die Indizes für einige Tabellen angepasst wurden, um eine rationalere Spaltenreihenfolge zu erzielen. Dies reduzierte unsere Verriegelungsprobleme erheblich.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.