Montag, Februar 10, 2020

MVCC Verhalten bei Oracle, Postgres und dem SQL Server

Franck Pachot zeigt in einem aktuellen Artikel, dass der SQL Server in Sachen MVCC immer noch deutlich anders agiert als Oracle und Postgres. Zur Erinnerung: Microsofts Interpretation des Isolation Levels "read committed" hat in der Vergangenheit immer wieder zu Diskussionen geführt, da hier nicht wie bei Postgres und Oracle ein für den Startzeitpunkt der Query konsistenter Zustand gelesen wird, sondern zum Zeitpunkt des Zugriffs abgerufen wird, was per commit festgeschrieben wurde. Dadurch kann eine lang laufende Query inkonsistente Ergebnisse liefern. Es gibt zwar immer wieder Interpreten, die das für eine sehr plausible Implementierungs-Variante halten, aber zu diesen gehöre ich nicht. Noch problematischer ist wahrscheinlich, dass sich trotzdem im SQL Server mit diesem Isolation Level immer wieder Situationen ergaben, in denen writer durch reader und reader durch writer blockiert wurden, was dazu führte, dass manche SQL Server Applikation auf das Isolation Level "read uncommitted" (aka dirty read) umstellte, was zwar Sperren vermied, aber die Frage der Konsistenz der Daten noch weiter in den Hintergrund drängte. Aus diesem Grund hat Microsoft schließlich das Isolation Level "read committed snapshot" eingeführt, das die Bereitstellung lesekonsistenter Ergebnisse sicherstellt (und aus meiner Sicht stärker der Postgres-Implementierung von MVCC ähnelt als der von Oracle, da hier explizit historische Daten vorgehalten werden, so lange sie von Transaktionen benötigt werden).

Frank Pachot zeigt nun in seinem Artikel, dass selbst der Isolation Level "read committed snapshot" stärkere Locking-Effekte hervorrufen kann als die MVCC-Implementierungen von Oracle und Postgres. Vermeiden kann man diese Effekte nur durch ergänzende Indizes (und unter Umständen auch Hints). Die Ursache dafür fasst der Herr Pachot so schön zusammen, dass ich sie hier einfach zitiere:
A DML statement has two phases: one to find the rows and the second one to modify them. A DELETE or UPDATE in Oracle and Postgres runs the first in snapshot mode: non-blocking MVCC. The second must, of course, modify the current version. This is a very complex mechanism because it may require a retry (restart) when the current version does not match the consistent snapshot that was used for filtering. Both PostgreSQL and Oracle can ensure this write consistency without the need to block the reads. SQL Server has implemented MVCC more recently and provides non-blocking reads only for the SELECT reads. But a read can still be in blocking situation for the query phase of an update statement.
Mir zumindest war bisher nicht aufgefallen, dass "read committed snapshot" hier weiterhin ein anderes Verhalten zeigt, als "read committed" in Postgres und Oracle.

Keine Kommentare:

Kommentar veröffentlichen