Probleme beim Sperren der Datenbank?

7

Ich habe ein transaktionsbezogenes Problem in einer SQL Server 2008-Produktionsdatenbank festgestellt. Eine kurze Übersicht ist, dass wir eine Website haben, auf der zahlreiche Benutzer im ganzen Bundesstaat gleichzeitig arbeiten und die über eine ASP.Net-Website GUI-ähnliche Arbeiten (Hinzufügen von Datensätzen, Ändern, Anzeigen usw.) ausführen.

Jedes Einfügen und Aktualisieren erfolgt in einer eigenen Transaktion, die von der Datenzugriffsschicht verwaltet wird. Ich glaube, die Datenbankisolation ist auf Read_Commited gesetzt.

Alles funktioniert gut.

Es wurde jedoch ein neues Modul hinzugefügt, das eine separate Datenbank nach Informationen abfragt. Wenn neue Informationen vorhanden sind, startet ein Prozess eine neue Transaktion und verwendet denselben Datenzugriffscode zum Lesen aus unserer Datenbank sowie zum Lesen der neuen Informationen aus einer anderen separaten Datenbank. Anschließend werden zahlreiche Überprüfungen durchgeführt, um festzustellen, was mit den neuen Daten geschehen muss. Anschließend werden zahlreiche Aktualisierungen oder Einfügungen in unsere Datenbank vorgenommen. Dies ist alles innerhalb einer großen Transaktion. Alle Einfügungen und Aktualisierungen sowohl der UI-Anwendung als auch des Abfragedienstes durchlaufen dieselben CRUD-Verfahren. Da eine eingehende Nachricht, die verarbeitet werden soll, viele Entitäten enthalten kann, die aktualisiert werden müssen, kann die Zeit für den Abschluss einer Transaktion zwischen einem Sekundenbruchteil und einer Minute liegen.

Wir stellen jedoch fest, dass die Benutzeroberfläche bei der Verarbeitung einer größeren Nachricht blockiert und für einen Benutzer für 3 Minuten gesperrt werden kann.

Wir dachten also, dass das Hinzufügen von 'NOLOCK'-Hinweisen zu den Auswahlen hilfreich sein könnte. Es war nicht so. Nun, es hat vielleicht ein bisschen geholfen, aber die Abstürze passieren immer noch.

Ich dachte, dass die Ursache möglicherweise darin besteht, dass die Nachricht eintrifft und eine Transaktion gestartet wird, die andere Transaktionen daran hindert, zu funktionieren (sogar SELECT-Anweisungen, die ich nicht verstehe). Die Profilerstellung in der Datenbank zeigt, dass selbst einfache Auswahlen auf der Benutzeroberfläche einige Zeit in Anspruch nehmen (zSELECT fields FROM SingleTable WHERE PrimaryKey = Value

Unsere Indizes scheinen in Ordnung zu sein ... Wir haben Trigger für alle Tabellen, die einfach Aktualisierungen und Einfügungen in eine AUDIT-Datenbanktabelle kopieren. Glaube nicht, dass sie das Problem sind.

Ich denke, das liegt an der Transaktion rund um die Nachrichtenverarbeitung, die die Benutzeroberfläche sperrt.

Kann jemand vielleicht eine Erfahrung teilen oder mir sagen, wo ich nachsehen kann, warum wir UI-Sperren bekommen? Die Benutzeroberfläche sollte Priorität haben. Die Nachrichtenverarbeitung ist eine Hintergrundsache ... die Benutzer müssen Priorität haben ... aber es scheint, dass die Nachrichten die Datenbank sperren ... und wir sind uns nicht sicher, ob die Benutzeroberfläche jemals die Nachrichtenverarbeitung sperrt.

Hoffe jemand kann helfen. Ich kann so viele Informationen wie möglich zur Verfügung stellen, um zu helfen.

Craig
quelle

Antworten:

4

Versuchen Sie, die RCSI ( Read Committed Snapshot Isolation ) zu aktivieren (beachten Sie jedoch, dass dies einen erhöhten Druck auf Ihre TempDB ausübt, die sich idealerweise auf einem eigenen Satz dedizierter physischer Spindeln befinden sollte).

Ab SQL Server 2005 stehen zwei Snapshot-Ebenen zur Verfügung: READ COMMITTED SNAPSHOT führt optimistische Lesevorgänge und pessimistische Schreibvorgänge durch. Während SNAPSHOT ISOLATION optimistische Lese- und Schreibvorgänge ausführt. Schlagen Sie vor, RCSI zu versuchen.

Aktivieren von Isolationsstufen auf Basis der Zeilenversionierung

Um diese Einstellung zu ändern, müssen Sie in den Einzelbenutzermodus wechseln, um sicherzustellen, dass sich keine Abfragen im Flug befinden (die dann fehlschlagen würden):

ALTER DATABASE dbname 
SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 
GO

ALTER DATABASE dbname
SET READ_COMMITTED_SNAPSHOT ON; 
GO

ALTER DATABASE dbname
SET MULTI_USER; 
GO
Mitch Wheat
quelle
Wir haben es versucht - aber es schien nicht zu helfen. Wenn wir die Infrastruktur-Chaps bestanden haben, sind die DBAs nicht zufrieden mit der Aktivierung der Snapshot-Isolation, da sie DB-weit aktiviert werden muss. Ich werde noch einmal darauf eingehen, aber die Datenbankadministratoren sagten, wir müssten diese Option genauer analysieren.
2
"Wir haben es versucht - aber es schien nicht zu helfen" - Schlagen Sie vor, diese wichtigen Informationen in Ihre Frage aufzunehmen. Was ist Ihre tempDB-Konfiguration? Haben Sie Ihre E / A-Subsysteme bewertet?
Mitch Wheat
Danke Mitch - meine Tests waren nicht sehr lang ... Also werde ich es am Montag erneut versuchen. Sie werden sich jedoch fragen, welche Auswirkungen dies auf den Rest des Systems haben würde. Klingen die oben genannten Symptome auch nach Sperrproblemen, die durch die große Transaktion verursacht wurden?
2

Das Problem des Blockierens von Sitzungen wurde bereits einige Male erörtert.

Ich bin sicher, dass Sie in den folgenden Fragen einige gute Referenzen finden können:

Zuerst müssen Sie herausfinden, ob Sie wirklich ein Blockierungsproblem haben. Dies kann ad-hoc mithilfe der gespeicherten WhoIsActive-Prozedur von Adam Machanic (die manuell ausgeführt werden muss, wenn Sie glauben, dass Ihre spezifische Sitzung blockiert ist oder automatisiert werden kann) oder eines anderen Berichts, der Blockierungssitzungen anzeigt, leicht ad-hoc gefunden werden . Um die Zeiten und die Dauer der Blockierungssituationen besser zu verstehen, sollten Sie einige serverseitige Traces vorbereiten , die die erforderlichen Informationen zu blockierten Sitzungen sammeln.

Details zum Finden und Bekämpfen von Blockierungen finden Sie in dieser Antwort .

Marian
quelle