Grundidee MVCC
Statt Datensaetze direkt zu aendern 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 gueltig war. Damit blockieren sich Leser und Schreiber nie gegenseitig.
Nie ueberschreiben, 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 Lesevorgaenge 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 abgeloest ist. Eine Transaktion T mit Zeitstempel ts sieht genau die Version, fuer 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 gegenueber 2PL: Lesetransaktionen brauchen keine Sperre. Auch waehrend ein Schreiber eine Zeile modifiziert, sehen andere Transaktionen ungestoert die alte Version. In OLTP-Systemen und bei Reporting-Queries neben laufendem Tagesgeschaeft 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 spaeter durch VACUUM aufgeraeumt. 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 (loeschen bedeutet eine Version mit end-ts markieren, nicht physisch entfernen). Ein Umstieg auf MVCC kann nicht rueckwirkend gemacht werden.
MVCC beruehrt 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, koennen aber zu Deadlocks fuehren. MVCC ist demgegenueber optimistisch fuer Reads: statt zu sperren wird eine neue Version angelegt. Write-Write-Konflikte muessen aber weiterhin erkannt werden.
2PL sperrt, MVCC vervielfaeltigt. Reads sperrfrei, Writes bleiben serialisiert.