7.2 Commit-Behandlung
7.2.4 Optimierungen von 2PC-Verfahren
Zwei Optimierungen von 2PC-Verfahren haben wir bereits diskutiert. Zum einen die Presumed-Abort-Optimierung und zum anderen die Verlagerung der Commit-Verantwortung zum letzten Agenten (lineares 2PC), welche vor allem für N=2 zu empfehlen ist. Wir beschreiben im folgenden zwei weitere 2PC-Optimierungen, mit denen Nachrichten und/oder (synchrone) Logging-Vorgänge eingespart werden können.
Optimierung lesender Sub-Transaktionen
Für Sub-Transaktionen, die keine Änderungen vorgenommen haben (read only), kann das Commit-Protokoll stark optimiert werden. Für solche Sub-Transaktionen ist weder ein Logging noch eine (Undo/Redo-) Recovery erforderlich. Im Rahmen der Commit-Behandlung sind für die Lese-Sub-Transaktionen daher lediglich die Sperren freizugeben. Dies kann jedoch bereits in Phase 1 eines 2PC-Protokolls erfolgen, da dies erforderlich ist unabhängig davon, ob die globale Transaktion erfolgreich zu Ende kommt oder abgebrochen werden muß. Folglich kann die zweite Commit-Phase für Lese-Sub-Transaktionen eingespart werden. Wenn M der N-1 Sub-Transaktionen Leser sind (M < N), reduziert sich damit die Nachrichtenanzahl im Basisprotokoll um 2M auf 4*(N-1) - 2M Nachrichten. Weiterhin verringert sich die Anzahl von Log-Schreibvorgängen auf 2N-M. Für reine Lesetransaktionen (M=N) werden keinerlei Log-Zugriffe sowie lediglich 2*(N-1) Nachrichten benötigt.
Viele existierende Datenbanksysteme verwenden lediglich "kurze" Lesesperren, die nicht bis zum Transaktionsende, sondern nur für die Dauer einer DB-Operation gehalten werden. Es wird dabei keine Serialisierbarkeit mehr erreicht[29], jedoch wird dies in vielen Anwendungen zur Reduzierung der Konflikthäufigkeit in Kauf genommen. In diesem Fall kann die Commit-Behandlung für lesende Sub-Transaktionen sogar vollständig entfallen, da die Lesesperren zum Commit-Zeitpunkt bereits freigegeben sind. Für reine Lesetransaktionen ist daher kein Commit-Protokoll auszuführen. Anderenfalls (M<N) reduziert sich die Nachrichtenanzahl auf 4*(N-M-1).
1-Phasen-Commit
Bisher wurde angenommen, daß die von Sub-Transaktionen verrichtete "Arbeit" (DB-Operationen bzw. Teiloperationen) getrennt vom Commit-Protokoll durchgeführt wird. Wie Abb. 7-7a für das Basis-2PC-Protokoll zeigt, werden zur eigentlichen Transaktionsbearbeitung Sub-Transaktionen (S) über WORK-Aufrufe von der Primär-Transaktion (P) bzw. einer anderen Sub-Transaktion aufgefordert, bestimmte Operationen zu erledigen. Das Ergebnis wird über eine DONE-Nachricht zurückgeliefert. Das Commit-Protokoll wird dann am Transaktionsende wie beschrieben mit eigenen Nachrichten ausgeführt. Diese Vorgehensweise führt jedoch vor allem für kurze (verteilte) Transaktionen, die z.B. nur eine externe DB-Operation erfordern (etwa eine Überweisungs-Transaktion), dazu, daß ein Großteil der Bearbeitungszeit auf die Commit-Behandlung entfällt
Abb. 7-7: Zwei-Phasen- vs. Ein-Phasen-Commit
.
Vor allem in solchen Fällen empfiehlt es sich als Optimierung, die PREPARE-Aufforderung bereits mit dem WORK-Aufruf zu kombinieren (Abb. 7-7b). Die Sub-Transaktion geht dann unmittelbar nach Durchführung ihrer Operationen und vor Rückmeldung an die rufende (Primär-) Transaktion in den Prepared-Zustand. Damit kann die erste Commit-Phase eingespart werden, so daß die eigentliche Commit-Bearbeitung nur noch aus einer Phase zur Mitteilung des Ergebnisses besteht ("1-Phasen-Commit"). Es werden somit pro Agent zwei Nachrichten eingespart. Eine weitere Nachricht kann für N=2 eingespart werden, wenn das Protokoll mit dem Transfer der Commit-Koordinierung kombiniert wird (Abb. 7-7c). In diesem Fall wird mit dem WORK-Aufruf gleichzeitig die Commit-Koordination an den Agenten der betreffenden Sub-Transaktion übergeben. Nach Ausführung der Sub-Transaktion trifft der Agent daraufhin bereits die globale Commit-Entscheidung und teilt diese mit der DONE-Nachricht mit. Die Primär-Transaktion sendet lediglich noch eine ACK-Nachricht an den neuen Commit-Koordinator.
Das Ein-Phasen-Commit ohne Transfer der Commit-Koordinierung ist nicht auf zwei Rechner beschränkt. Wenn während einer Transaktion mehrere WORK-Aufrufe an denselben Rechner notwendig werden, dann sollte nur für den letzten die Kombination mit der PREPARE-Aufforderung vorgenommen werden, da ansonsten unnötiger Logging-Aufwand eingeführt würde. Ein potentielles Problem liegt darin, daß sich durch den frühzeitigen Übergang in den Prepared-Zustand die Wahrscheinlichkeit einer Blockierung erhöht. Das Ausmaß dieser Gefahr hängt natürlich davon ab, wieviel weitere Arbeit in einer globalen Transaktion noch auszuführen ist, nachdem eine Sub-Transaktion bereits in den Prepared-Zustand übergegangen ist. Für einfache Transaktionen ist dies kein Problem, bei einer größeren Rechneranzahl dagegen kann die Blockierungswahrscheinlichkeit deutlich steigen. Allerdings läßt sich das Ein-Phasen-Commit leicht mit dem Zwei-Phasen-Commit kombinieren. So könnte die Optimierung auf die am Ende einer globalen Transaktion auszuführenden Sub-Transaktionen beschränkt werden.
[29] Man spricht i.a. von Konsistenzebene 2 oder "Cursor Stability", die in diesem Fall vorliegt. Im SQL92-Standard wird der mit kurzen Lesesperren einhergehende Isolationsgrad als "Read Committed" bezeichnet. Eine mögliche Folge kurzer Lesesperren ist die Anomalie "Non-Repeatable Read". Eine Transaktion kann also beim mehrmaligen Lesen eines Objektes unterschiedliche Zustände sehen, da die zwischenzeitliche Freigabe der Lesesperre eine parallele Änderung des Objektes ermöglicht. Schreibsperren werden generell bis Transaktionsende gehalten.
- Optimierung lesender Sub-Transaktionen
-
- 1-Phasen-Commit
-