MVCC als eine Möglichkeit, die Transaktionsisolation sicherzustellen

Hallo Habr. Ich heiße Vladislav Rodin. Derzeit bin ich Leiter des High Load Architect-Kurses bei OTUS und unterrichte auch Kurse zur Softwarearchitektur.

Speziell für den Start eines neuen Sets für den Kurs "Architekt hoher Lasten" habe ich ein kleines Material geschrieben, das ich gerne mit Ihnen teile.



Einführung


Letztes Mal haben wir mit Ihnen über die Folgen einer Schwächung der Transaktionsisolation in Datenbanken gesprochen. Heute werden wir einen der Wege, um diese Isolation und Vermeidung der betrachteten Anomalien sicherzustellen, genauer diskutieren. Wie Sie vielleicht bemerkt haben, wurden im letzten Artikel häufig zwei Ansätze unterschieden: Einer beruhte auf der Tatsache, dass die Datensätze einige Versionen haben , und der zweite auf der Tatsache, dass wir die Aufzeichnung auf die eine oder andere Weise blockieren werden . Somit werden zwei Klassen von Datenbanken unterschieden: versioniert und Blocker . Heute werden wir darüber sprechen, was Versionscontroller sind, und beim nächsten Mal die Berücksichtigung von Blockern verlassen.

Versionionisten


Wie gesagt, einer der Ansätze basiert auf der Versionierung. Es wird auch als optimistischer Ansatz oder MVCC (Multiversion Concurrency Control) bezeichnet . Tatsächlich erfolgt ein Versionsspeicher für aktive Transaktionen.

Wo sind die Versionen gespeichert?


Die Implementierung des Mechanismus hängt von der Datenbank ab. Ich werde einige Beispiele nennen.

PostgreSQL


Jede Transaktion ist durch ein id-shnik gekennzeichnet. Id-shnik-Transaktionen wachsen monoton. Jede Zeile verfügt über zwei Attribute, die Metainformationen für die Bereitstellung eines Mechanismus darstellen: updated_by_id - ID der Transaktion, die diesen Datensatz zuletzt aktualisiert hat, und delete_by_id - ID der Transaktion, die diesen Datensatz gelöscht hat. Wenn eine neue Transaktion eintrifft, ermittelt die Datenbank die ID-Nicks der aktuell ausgeführten Transaktionen. Die durch diese Transaktionen vorgenommenen Änderungen werden in der eingehenden Transaktion ignoriert. Es stellt sich heraus, dass die eingehende Transaktion wie mit ihrer Version der Daten funktioniert. Alte Versionen von Daten werden am selben Ort wie aktuelle gespeichert. Wenn Update eintrifft, wird eine weitere Zeile hinzugefügt und dieser Datensatz wird aktiv. Es ist auch klar, dass für den korrekten Betrieb dieses Schemas ein "Garbage Collector" erforderlich ist:Wenn ein Datensatz "delete_by_id = 100" hat und die minimale ID-shnik unter den aktuellen Transaktionen 150 beträgt, muss dieser Datensatz gelöscht werden.

MySQL (InnoDB-Engine)


In der MySQL-Datenbank wird nur die aktuelle Version gespeichert. Wenn Update eintrifft, werden die Daten in der Tabellendatei korrigiert. Nach dem Anpassen der Daten befindet sich die vorherige Version im Rollback-Protokoll. In MySQL gibt es mehrere Rollback-Protokolle (sie unterscheiden sich für insert'ov und update'ov). Wenn für eine Transaktion eine frühere Version der Zeile erforderlich ist, macht das System das Protokoll rückgängig und stellt die erforderliche Version wieder her. Die Version wird auch durch die Transaktions-ID bestimmt.

Orakel


Das Schema ähnelt MySQL: Die aktuellen Versionen werden in der Datendatei gespeichert, alte Versionen werden dank Rückgängig-Protokoll wiederhergestellt. Das Rückgängig-Protokoll in Oracle wird zyklisch neu geschrieben. Daher ist eine Situation möglich, in der eine Transaktion eine sehr alte Version des Datensatzes benötigt, diese jedoch im Rückgängig-Protokoll nicht mehr vorhanden ist. In diesem Fall schlägt die Transaktion fehl.

MS SQL


MS SQL ermöglicht die Einbeziehung von Versionierungs- und Blockermodi. Um den versionierten Modus in den Datenbankeinstellungen zu aktivieren, müssen Sie Snapshots aktivieren. In MS SQL gibt es eine Systemtabelle (tempdb), in der temporäre Tabellen gespeichert werden. Es ist Tempdb, das zum Speichern alter Versionen verwendet wird, während die Tabelle die aktuellen Versionen enthält. Der Systemprozess überwacht, dass es in Tempdb Versionen gibt, auf die sich niemand bezieht. Sie können gelöscht werden. Wenn die Transaktion lange dauert, werden Versionen dafür gespeichert. Tempdb wächst, erreicht seine maximale Größe, MS SQL reserviert ein wenig Speicherplatz. Wenn es endet, können Transaktionen mit Snapshot-Isolation nicht ausgeführt werden. Wenn diese Betriebsart verwendet wird, müssen lange Transaktionen überwacht werden.weil das Rollback einer solchen Transaktion in der Zeit so viel kosten kann, wie es funktioniert, und vielleicht ein bisschen mehr.

Konflikte


Dieser Ansatz wird als optimistisch bezeichnet, da wir hoffen, dass es keinen Konflikt gibt, wenn parallele Datenänderungstransaktionen ausgeführt werden. Was passiert im Konfliktfall? Angenommen, die Transaktion T1 ändert 10.000 Datensätze und die Transaktion T2 ändert 1 Datensatz parallel. Wenn dieser 1 Datensatz in diesen 10.000 enthalten ist, wird eine der Transaktionen zurückgesetzt: Wenn T1 zuerst ausgeführt wird, wird T2 zurückgesetzt, andernfalls umgekehrt.

Rollback-Mechanismus


Der Mechanismus des Transaktions-Rollbacks in versionierten Versionen hängt von der Implementierung ab. In PostgreSQL wird beispielsweise eine Transaktion als evakuiert markiert und durch Vakuum wird Speicherplatz freigegeben. Ein solcher Mechanismus ist schnell genug. In Oracle werden für das Rollback Daten aus dem Rückgängig-Protokoll wiederhergestellt. In diesem Fall erhöht sich die Betriebszeit, sie ist jedoch immer noch viel schneller als in Schließfächern. MySQL funktioniert genauso wie Oracle.

Fazit


Der optimistische Ansatz ist gut, da der Autor den Leser nicht blockiert, sondern einfach seine Version der Daten liest. Daher ist die Versionierung von Vorteil, wenn die Hauptlast eher beim Lesen als beim Schreiben liegt (Blog, Berichterstellung und andere Fälle, in denen Sie häufig und häufig lesen müssen).



Erfahren Sie hier mehr über den Kurs.



All Articles