Warum müssen nicht festgeschriebene Transaktionen in umgekehrter Reihenfolge rückgängig gemacht werden?


19

Ich habe ein Datenbankprotokoll, in dem einige Transaktionen gewinnen (sie werden vor dem Absturz festgeschrieben) und andere verlieren (noch nicht festgeschrieben). Wir haben in der Klasse gelernt, dass die Aktionen der Verlierer rückwärts rückgängig gemacht werden müssen.

Gibt es einen Grund, dies rückwärts zu tun? Kann jemand ein einfaches Beispiel für ein Protokoll geben, bei dem Forward-Rückgängigmachungen zu falschen Ergebnissen führen würden?


Sollte diese Frage nicht auf einer anderen spezifischeren Website gestellt werden?
nbro

Antworten:


35

Ursprüngliche Transaktionen:

  1. Datensatz einfügen .r
  2. Aktualisiere ein Feld von r .fr

Rückgängig machen:

  1. Datensatz löschen .r
  2. Machen Sie das Update rückgängig zu - oh warte, r existiert nicht mehr! Dies verursacht einen Fehler.rr

Müssen die Dinge physisch einzeln in umgekehrter Reihenfolge rückgängig gemacht werden, wenn das System herausfinden kann, auf welchen Status die Dinge zurückgesetzt werden müssen, und alle erforderlichen Änderungen vornehmen kann, bevor etwas anderes verarbeitet wird?
Supercat

11
Das Rückgängigmachen von Änderungen in umgekehrter Reihenfolge macht es einfach. Warum sollten Sie versuchen, es sich selbst schwer zu machen?
gnasher729

1
Nein, das System wird nicht alles tun , aber es wird dies in umgekehrter Reihenfolge herausfinden.
Evil

3
In vielen realen Datenbanksystemen wäre es nicht möglich, dies in umgekehrter Reihenfolge zu tun, da wichtige Einschränkungen für Tabellen bestehen.
SeanR

11

Um die Antwort von DylanSp zu ergänzen, schlägt der Versuch fehl, ein Feld in einem nicht vorhandenen Datensatz zu aktualisieren, aber das Ergebnis ist weiterhin das erwartete Ergebnis: Datensatz r ist nicht vorhanden.

Betrachten Sie jedoch eine Situation, in der das Löschen eines Datensatzes tatsächlich fehlschlägt:

  1. Geben Sie die Bestellnummer ein.
  2. Bestellzeile L einfügen.

Nehmen wir an, nicht unrealistisch, dass jede OrderLine mit einem Auftrag verknüpft sein muss .

Das Zurücksetzen der Transaktion, die mit dem Löschen der Bestellung beginnt, schlägt fehl, da dies gegen unsere Geschäftsregel verstoßen würde.

So danach

  1. Auftrag O. löschen (FAIL)
  2. Löschen Sie Ordeline L. (SUCCESS)

Möglicherweise haben wir eine bestehende Bestellung (ohne Bestellposten).

In diesem Fall könnten wir natürlich ein kaskadierendes Löschen verwenden, aber das würde bedeuten, dass Schritt 2 fehlschlagen würde (ohne Auswirkungen). Schlimmer noch, es kann unerwünschtes Verhalten sein, kaskadierende Löschvorgänge bei Aufträgen zu implementieren.


Okay, das macht Sinn. Danke für eure Hilfe
voraussichtlich

Ist es richtig anzunehmen, dass Einschränkungen vor oder nach der Transaktion unter "normalen" Umständen nicht verletzt wurden? Normalerweise meine ich, dass die Transaktion nicht fehlgeschlagen wäre, wenn nur eine Person die Datenbank verwendet hätte. Wenn dies zutrifft, warum ist es dann wichtig, während des Rückgängigmachens keine Verstöße gegen Einschränkungen einzuführen? Es scheint, dass Einschränkungen zu Beginn des Rückgängigmachens deaktiviert und aktiviert werden könnten, sobald der Vorgang abgeschlossen ist.
Noctis Skytower

2
@NoctisSkytower Durch Deaktivieren von Einschränkungen während eines normalen E / A-Vorgangs werden sie unbrauchbar. Sie existieren aus einem Grund. Mein Beispiel zeigt deutlich, wie Einschränkungen unter normalen Umständen erfüllt werden können, die jedoch beim Rollback verletzt werden. Das Deaktivieren von Einschränkungen während des Rollbacks verkompliziert unnötigerweise die Sache und behebt das falsche Problem. Das Problem ist nicht die Einschränkung, das Problem ist die Verletzung, indem falsch versucht wird, ein Rollback durchzuführen.
Oerkelens

Ja, das ist sinnvoll, aber warum sollten Einschränkungen während des Rollbacks überprüft werden? Angenommen, Rollbacks sind so konzipiert, dass sie garantiert problemlos abgeschlossen werden. Warum unnötig Zeit verschwenden, um Einschränkungen zu überprüfen, wenn bekannt ist, dass sie bis zum Abschluss des Rollbacks nicht verletzt werden? Übrigens, das sollte eine Garantie sein, denn wenn ein Rollback fehlschlägt, müsste die Datenbank anscheinend ein Rollback durchführen, was sie nicht kann.
Noctis Skytower

1
@NoctisSkytower Es sollte unmöglich sein, dass sich die Datenbank jemals in einem Zustand befindet, in dem die Einschränkungen verletzt werden, auch wenn es sich um einen temporären Zustand handelt. Wenn der gesamte Rollback atomar ist, spielt es keine Rolle, in welcher Reihenfolge er ausgeführt wird, da es keine Reihenfolge gibt. Es handelt sich um eine einzelne Anweisung, die "auf einmal ausgeführt wird". Wenn es zwei oder mehr Transaktionen gibt, die in einer bestimmten Reihenfolge separat zurückgesetzt werden, muss die Reihenfolge so sein, dass jeder Beobachter, der die Daten in der Mitte liest, nur eine Situation sehen kann, in der alle Einschränkungen gelten.
Peteris

6

Gehen wir analog: Sagen wir, Sie gehen zum Abendessen aus.

  1. Socken anziehen.
  2. Schuhe anziehen.
  3. Aufstehen.
  4. Gehen Sie zur Tür.

Dann bekommst du einen Anruf. Dinnerpläne abgesagt.

  1. Socken ausziehen.
  2. Schuhe ausziehen.
  3. Setz dich.
  4. Gehen Sie von der Tür weg.

Da läuft etwas schief. Sie könnten stolpern und sich verletzen. Oder es ist wahrscheinlicher, dass Sie feststellen, dass einige Aktionen erst rückgängig gemacht werden können, wenn spätere Aktionen zuerst rückgängig gemacht werden.

Wenn Sie das letzte, was Sie getan haben, rückgängig machen, kehren Sie zu dem Zeitpunkt zurück, als der vorletzte Schritt ausgeführt wurde. Dann machst du diesen Schritt rückgängig und wiederholst ihn, bis nichts mehr übrig ist. Andererseits ist das Umkehren des ersten Schritts möglicherweise nicht möglich, wenn die Zustände den späteren Schritten folgen.

Mathematisch gesprochen: Die Aktionen werden möglicherweise nicht umgesetzt. Wann immer es also darauf ankommt, welchen Schritt Sie zuerst oder zweitens ausführen, spielt die Reihenfolge, in der Sie Schritte rückgängig machen, eine Rolle.


3

Dies ist richtig, da Transaktionen aufeinander aufbauen und das Ergebnis einer Transaktion stark von der Situation vor dem Commit abhängt.

Schauen wir uns die Finanztransaktionen an:

(zu Beginn, bevor Transaktionen amir 100 USD schulden)

  1. a schuldet mir 100 USD (jetzt Gesamtschuld 200)
  2. aerhält 10% Rabatt auf das, was er mir schuldet. (jetzt Gesamtverschuldung 180)

Angenommen, ich möchte die beiden Transaktionen stornieren.

Wenn wir die erste zuerst stornieren, erhalten wir:

  1. niedrigere Schulden 100 (jetzt haben Schulden 80)
  2. 10% Rabatt stornieren (jetzt Schulden haben 80 / 0.9 = 88)

Das ist falsch, wir müssen die Schulden von 100 zurückzahlen. Das ist richtig, wenn wir die Transaktionen in umgekehrter Reihenfolge stornieren.

  1. Rabatt stornieren - jetzt ist die Verschuldung 200
  2. Schulden um 100 senken - jetzt sind es 100

2

Angenommen, es gibt eine Tabelle T mit nur einer Spalte.

Angenommen, das "Undo-Protokoll" ist eine Datenbankdatei, die nicht festgeschriebene Transaktionen enthält, und das "Redo-Protokoll" ist eine Datenbankdatei, die sowohl nicht festgeschriebene als auch festgeschriebene Transaktionen enthält, die noch nicht auf die Datendateien angewendet wurden.

At 8:00 A.M., Transaction 100 inserts rows with values 101, 102 and 103 into table T. At 8:10 A.M., Transaction 100 is committed and the commit for transaction 100 completes. At 8:15 A.M., Transaction 200 updates row 101 to 201, 102 to 202 and 103 to 203. At 8:20 A.M., Transaction 200 has not been committed and remains in the undo log of the database. At 8:25 A.M., Transaction 300 increments each row by 50, changing row 201 to 251, 202 to 252, and 203 to 253. At 8:30 A.M., Transaction 300 has not been committed and remains in the undo log of the database. At 8:35 A.M., The instance providing access to the database crashes.

At 8:40 A.M., The instance is restarted, and the database files are opened as the instance is started:

              The committed values in T are still 101, 102 and 103.

              Since 201, 202, and 203, and 251, 252 and 253
              are not committed, if they are written into the "redo
              log" of the database, there is a need to "roll back"
              the transactions AFTER the "redo log" is applied.

              Since 201, 202, and 203, and 251, 252 and 253
              are not committed, they are in the "undo log"
              of the database.

              The undo log of the database is used BOTH to (1) roll
              back a transaction that is deliberately rolled 
              back in the memory structure of the database instance, 
              and also (2) during the instance recovery at 8:40 A.M.

At 8:41 A.M., The redo log has been applied, and the T table contains values 251, 252 and 253 in the instance memory.

              The undo log has not yet been applied.

At 8:42 A.M., The undo log is applied in the reverse order: Uncommitted transaction 300 is undone, and Uncommitted transaction 200 is undone.

Warum werden BEIDE festgeschriebenen und nicht festgeschriebenen Transaktionen in die Redo-Log-Datei geschrieben? Der Grund hierfür ist die Bereitstellung einer Wiederherstellung zu einem bestimmten Zeitpunkt.

Dies bedeutet, dass der Inhalt der Datei "Redo Log" NICHT transaktionskonsistent ist. Aus diesem Grund MUSS das "Rückgängig-Protokoll" immer dann verwendet werden, wenn das Redo-Protokoll verwendet wird, um festgeschriebene Transaktionen auf die Datendateien anzuwenden, um nicht festgeschriebene Transaktionen zurückzusetzen.

Warum werden die Transaktionen im "Undo-Log" in umgekehrter Reihenfolge zurückgesetzt? Die Transaktion 300 hat zu dem vorhandenen Wert jeder Spalte jeder Zeile 50 addiert. Wenn daher die Transaktion 200 zuerst zurückgesetzt wird, ändern sich die Werte von 251, 252 und 253 zu 201, 202 und 203. Wenn die Transaktion 300 dann zuletzt zurückgesetzt würde, wären die Werte 151, 152 und 153 - die nicht übereinstimmen die ursprünglich zugesagten Werte.

VERWEISE:

https://asktom.oracle.com/pls/asktom/f?p=100:11:0:::P11_QUESTION_ID:1670195800346464273


0

Es ist nicht von Natur aus wahr. Beim Rollback werden die im Rückgängig-Protokoll zwischengespeicherten Blöcke möglicherweise erneut angewendet, sodass der endgültige Status dem ursprünglichen Status entspricht. Da das Protokoll in Vorwärtsreihenfolge geschrieben wurde, habe ich mein Rollback auch in Vorwärtsreihenfolge angewendet. Die Reihenfolge spielte keine Rolle, da das Rollback so lange wiederholt wurde, bis die Protokolldatei als erledigt markiert wurde.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.