Grundidee MVCC
Statt Datensätze direkt zu ändern legt das DBMS bei jedem Write eine neue Version des Datenobjekts an. Jedes logische Objekt existiert also physisch in mehreren Versionen gleichzeitig. Ein Lesen greift immer auf die Version zu, die zu Beginn der eigenen Transaktion gültig war. Damit blockieren sich Leser und Schreiber nie gegenseitig.
Nie überschreiben, immer eine neue Version anlegen und lesen aus dem eigenen Snapshot.
Snapshot Isolation
Snapshot Isolation ist die Isolationsstufe, die MVCC praktisch umsetzt. Zu Beginn einer Transaktion bekommt diese einen logischen Zeitstempel, ihren Snapshot. Alle Lesevorgänge sehen den Datenbankzustand exakt so, wie er zu diesem Zeitstempel committed war. Snapshot Isolation ist NICHT identisch zu Serializable, das write-skew Problem kann noch auftreten.
Snapshot = konsistente Sicht zum Startzeitpunkt der Transaktion.
Versionen und Zeitstempel
Jede physische Version einer Zeile bekommt zwei Zeitstempel: begin-ts markiert, ab wann sie sichtbar wird, end-ts markiert, ab wann sie durch eine neuere Version abgelöst ist. Eine Transaktion T mit Zeitstempel ts sieht genau die Version, für die gilt begin-ts <= ts und (end-ts unbekannt oder end-ts > ts).
begin-ts, end-ts, value plus Tx-Status-Tabelle sind die Datenstrukturen von MVCC.
Kein Blockieren bei Reads
Der praktische Kernvorteil von MVCC gegenüber 2PL: Lesetransaktionen brauchen keine Sperre. Auch während ein Schreiber eine Zeile modifiziert, sehen andere Transaktionen ungestört die alte Version. In OLTP-Systemen und bei Reporting-Queries neben laufendem Tagesgeschäft ist das der entscheidende Durchsatz-Vorteil.
Reads gehen nie in eine Warteschlange, Writes ebenfalls nicht wegen Reads.
MVCC in Postgres und Oracle
Postgres implementiert MVCC direkt in den Heap-Tuples: jede Zeile hat xmin und xmax als versteckte Systemspalten. Updates erzeugen physisch eine neue Zeile, alte Zeilen werden später durch VACUUM aufgeräumt. Oracle nutzt stattdessen Undo-Segmente: alte Werte landen im Rollback-Segment, aus dem Leser bei Bedarf die passende alte Version rekonstruieren.
Postgres speichert Versionen im Heap, Oracle rekonstruiert sie aus Undo-Segmenten.
Auswirkungen im DBMS
MVCC ist mehr als ein Sperr-Protokoll und wirkt sich auf mehrere Komponenten aus: Concurrency Control Protocol, Version Storage, Garbage Collection, Index Management und Deletes (löschen bedeutet eine Version mit end-ts markieren, nicht physisch entfernen). Ein Umstieg auf MVCC kann nicht rückwirkend gemacht werden.
MVCC berührt Concurrency, Storage, GC, Index und Deletes gleichermassen.
Abgrenzung zu 2PL
Beim Two-Phase-Locking fordern Transaktionen S- und X-Sperren an. Sperren sind pessimistisch: sie verhindern Konflikte durch Blockieren, können aber zu Deadlocks führen. MVCC ist demgegenüber optimistisch für Reads: statt zu sperren wird eine neue Version angelegt. Write-Write-Konflikte müssen aber weiterhin erkannt werden.
2PL sperrt, MVCC vervielfältigt. Reads sperrfrei, Writes bleiben serialisiert.