Zusammenfassung

⭐ Laut Dozent: MVCC (Multiversion Concurrency Control) ist explizit als Schwerpunkt genannt.
MVCC (Multiversion Concurrency Control) ist ein Verfahren zur Nebenläufigkeitskontrolle, bei dem das DBMS statt Datensätze direkt zu überschreiben mehrere Versionen jedes Datenobjekts vorhält. Jede Transaktion arbeitet auf einem konsistenten Snapshot der Datenbank zum Startzeitpunkt, wodurch sich Leser und Schreiber niemals gegenseitig blockieren. MVCC ist die Grundlage von Snapshot Isolation und wird von PostgreSQL, Oracle und praktisch allen modernen OLTP-Systemen eingesetzt.

Kernkonzepte

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.

Wichtige Details

  • MVCC = Multiversion Concurrency Control: mehrere physische Versionen pro logischem Datenobjekt.
  • Beim Write wird immer eine neue Version angelegt, die alte Version bekommt einen end-ts und bleibt zunächst erhalten.
  • Beim Read wird die Version zurückgegeben, die zum Startzeitpunkt der eigenen Transaktion gültig war (Snapshot).
  • Zentraler Merksatz: Writers do not block readers, readers do not block writers.
  • Datenstruktur je Version: begin-ts, end-ts, value. Zusätzlich Tx-Status-Tabelle: txnid, timestamp, status (Active/Committed/Aborted).
  • MVCC ist die Grundlage von Snapshot Isolation, verhindert Dirty Read, Nonrepeatable Read und (weitgehend) Phantom-Probleme.
  • MVCC wirkt sich auf: Concurrency Control, Version Storage, Garbage Collection, Index Management und Deletes aus.
  • Postgres implementiert MVCC direkt im Tuple-Header (xmin/xmax), Oracle nutzt Undo-Segmente.
  • Nachteil: Speicherverbrauch steigt durch alte Versionen, deshalb ist Garbage Collection (VACUUM in Postgres) nötig.
  • MVCC allein garantiert NICHT vollständige Serialisierbarkeit (write-skew möglich), dafür braucht es SSI.

Beispiele

MVCC Grundablauf mit Versionstabelle

Klassisches Beispiel aus der Vorlesung: T1 liest A während T2 A parallel ändert. Beide blockieren sich nicht.

Zustand: A0 (begin-ts=0, end-ts=inf, value=123)

Historie:
T1: BEGIN (ts=1)
T1: R(A) -> liest A0 = 123
T2: BEGIN (ts=2)
T2: W(A) -> DBMS erzeugt neue Version A1 (begin-ts=2, value=456)
              alte Version A0 bekommt end-ts=2
T1: R(A) -> liest weiterhin A0 = 123 (Snapshot bei ts=1)
T1: COMMIT
T2: COMMIT

Ergebnis Datenbanktabelle:
A0: begin-ts=0, end-ts=2, value=123
A1: begin-ts=2, end-ts=-, value=456

=> T1 blockiert nicht, sieht konsistenten Snapshot

Bank-Überweisung ohne Blockieren durch Reporting

T1 führt Überweisung durch, T2 macht parallel Bilanzsumme. Bei 2PL würde T2 warten, mit MVCC liest T2 einen konsistenten Snapshot.

T1 (Überweisung 50 von A nach B)   T2 (Reporting: Sum(A)+Sum(B))
BEGIN ts=10                          BEGIN ts=11
read(A) -> 1000
A := A - 50
write(A) -> neue Version A_v11=950
                                     read(A) -> sieht alte Version=1000
                                     read(B) -> sieht alte Version=500
read(B) -> 500                       Summe=1500 (konsistent zum Zeitpunkt ts=11)
B := B + 50                          COMMIT
write(B) -> neue Version B_v12=550
COMMIT

=> Keine Sperren, keine Wartezeit, T2 sieht konsistenten Zustand vor der Überweisung.

Verhinderung Nonrepeatable Read durch Snapshot

Unter 2PL wäre in Read Committed ein Nonrepeatable Read möglich. Mit MVCC/Snapshot Isolation wird dies verhindert.

T1 (Kontostand lesen)          T2 (Update)
BEGIN (Snapshot bei ts=5)
SELECT guthaben FROM Konten
WHERE iban=4711 -> 1000
                               BEGIN
                               UPDATE Konten SET guthaben=guthaben+100
                               WHERE iban=4711
                               COMMIT (neue Version bei ts=8)
SELECT guthaben FROM Konten
WHERE iban=4711 -> immer noch 1000
(liest weiter die Version, die bei ts=5 gültig war)
COMMIT

=> Repeatable Read wird durch MVCC automatisch erreicht.

Postgres/Oracle Praxis

Anschauliches Verhalten in konkreten DBMS. In Postgres ist Read Committed Default und funktioniert komplett über MVCC.

Postgres Session 1:               Postgres Session 2:
BEGIN;
SELECT balance FROM konto
  WHERE id=1;  -- 100
                                  BEGIN;
                                  UPDATE konto SET balance=200
                                    WHERE id=1;
                                  -- kein Blockieren für Leser
SELECT balance FROM konto
  WHERE id=1;  -- 100 (Session 1 wartet NICHT)
                                  COMMIT;
SELECT balance FROM konto
  WHERE id=1;  -- unter READ COMMITTED: 200
                -- unter REPEATABLE READ: 100
COMMIT;

Grafik: MVCC Ablauf

Zeitachse T1 und T2 T1 (ts=1) T2 (ts=2) BEGIN R(A)=123 R(A)=123 COMMIT BEGIN W(A)=456 COMMIT Datenbanktabelle begin-ts end-ts value 0 2 123 (A0) 2 - 456 (A1) Tx-Status txnid ts status T1 1 Committed T2 2 Committed liest A0 erzeugt A1 Writers do not block readers Readers do not block writers Sichtbarkeitsregel: Version V sichtbar für Transaktion T mit Zeitstempel ts, wenn gilt: V.begin-ts <= ts UND (V.end-ts ist leer ODER V.end-ts > ts) Legende: Reader (T1) Writer (T2) alte Version aktuelle Version T1 mit ts=1 sieht A0. T2 legt A1 an. T1 sieht auch nach W(A) durch T2 weiterhin A0.

FAQ - Häufige Fragen

Was ist der zentrale Unterschied zwischen MVCC und 2PL?
2PL nutzt Sperren, Leser können Schreiber blockieren und umgekehrt. MVCC hält mehrere Versionen jedes Datensatzes vor. Leser bekommen die Version, die zu Beginn ihrer Transaktion gültig war, Schreiber legen eine neue Version an. Damit blockieren sich Reads und Writes nicht gegenseitig.
Was passiert bei einem Rollback unter MVCC?
Die neu erzeugte Version wird einfach als ungültig markiert bzw. später vom Garbage Collector entfernt. Die alte Version bleibt sichtbar. Kein aufwändiges Undo der bestehenden Zeilen ist nötig.
Was ist Snapshot Isolation?
Snapshot Isolation ist die Isolationsstufe, die auf MVCC basiert. Jede Transaktion arbeitet auf einem konsistenten Snapshot der Datenbank zum Startzeitpunkt. Sie sieht nur Änderungen, die zu diesem Zeitpunkt bereits committed waren, plus die eigenen Änderungen.
Wie werden alte Versionen wieder aus der Datenbank entfernt?
Über Garbage Collection. Sobald keine aktive Transaktion mehr eine bestimmte alte Version braucht (also alle laufenden TAs sind jünger als end-ts der Version), kann sie physisch gelöscht werden. In Postgres macht das der VACUUM-Prozess.
Verhindert MVCC alle vier Concurrency-Probleme?
MVCC verhindert Dirty Reads, Nonrepeatable Reads und Lost Updates zuverlässig. Klassische Phantoms sind ebenfalls weitgehend eliminiert. Es gibt jedoch das write-skew Problem, das reine Snapshot Isolation nicht abfängt. Dafür braucht es Serializable Snapshot Isolation.
Warum wirkt sich MVCC auf mehr als nur das Concurrency-Protokoll aus?
Weil neue Versionen gespeichert werden müssen (Version Storage), alte Versionen aufgeräumt werden müssen (Garbage Collection), Indizes mehrere Versionen adressieren müssen (Index Management) und auch Deletes eine spezielle Behandlung brauchen (logisches Löschen über end-ts).
Welche Metadaten hängen an einer Version?
Jede Version einer Zeile bekommt einen begin-ts (ab wann sichtbar), einen end-ts (bis wann gültig, - bedeutet aktuell) und den value. Ergänzend gibt es eine Transaction-Status-Tabelle mit txnid, timestamp und status (Active, Committed, Aborted).
Welche DBMS setzen MVCC ein?
PostgreSQL, Oracle, MySQL InnoDB, SAP HANA, SQL Server (ab optionalem Snapshot Isolation Mode), CockroachDB und praktisch alle modernen verteilten SQL-Systeme. MVCC ist heute der De-facto-Standard für OLTP-Systeme.

Prüfungsfragen

0 von 12 Fragen beantwortet 0%