Einführung Als ich mehr über die Datenbanktheorie erfuhr, erfuhr ich von den möglichen Problemen, die mit unterschiedlichen Isolationsstufen von Dingen verbunden sind. Zum besseren Verständnis haben wir diese Probleme in der MySQL-Datenbank getestet und reproduziert. Dirty Reads und nicht wiederholbare Reads können unter den entsprechenden Isolationsebenen problemlos reproduziert werden. Was Phantom-Lesevorgänge betrifft, stellte ich jedoch fest, dass diese unter der Isolationsstufe für wiederholbare Lesevorgänge nicht auftraten. Damals dachte ich, dass MySQL vielleicht etwas gegen Phantom-Lesevorgänge unternommen hat? prüfen: Erstellen Sie eine Testtabelle dept: CREATE TABLE `dept` ( `id` int(11) NICHT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, PRIMÄRSCHLÜSSEL (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 insert into dept(name) values("Logistikabteilung")
Gemäß dem obigen Prozess wird erwartet, dass die erste Auswahl von Transaktion 1 ein Datenelement abfragt und die zweite Auswahl zwei Datenelemente abfragt (einschließlich der von Transaktion 2 übermittelten Daten). Allerdings stellte sich im Praxistest heraus, dass die zweite Auswahl tatsächlich nur ein Datenelement abfragt und verarbeitet. Gemäß der Implementierung des wiederholbaren Lesens in der Datenbanktheorie (exklusive Sperren und gemeinsam genutzte Sperren) sollte dies jedoch nicht der Fall sein. Bevor wir die eigentlichen Gründe verstehen, wollen wir die relevanten Theorien dazu durchgehen. Datenbankprinzipien Theorie Ding Mit Transaktion ist im Allgemeinen etwas gemeint, das getan werden muss oder erfolgt. In der Computersprache bezeichnet es eine Programmausführungseinheit, die auf verschiedene Datenelemente in einer Datenbank zugreift und diese ggf. aktualisiert. Eine Transaktion besteht aus allen Vorgängen, die zwischen dem Beginn und dem Ende einer Transaktion ausgeführt werden. In einer relationalen Datenbank kann eine Transaktion eine Reihe von SQL-Anweisungen oder ein ganzes Programm sein. Warum haben wir Dinge? Eine Datenbanktransaktion besteht typischerweise aus einer Folge von Operationen, die Lese- oder Schreibvorgänge in der Datenbank durchführen. Es dient zwei Zwecken:
Eigenschaften der Dinge Transaktionen haben vier Eigenschaften: Atomarität, Konsistenz, Isolation und Dauerhaftigkeit. Diese vier Eigenschaften werden oft als ACID-Eigenschaften bezeichnet.
Einige Eigenschaften von Dingen stellen keine Menge gleichwertiger Konzepte dar: Wenn zu einem bestimmten Zeitpunkt nur eine Sache vorhanden ist, ist diese natürlich isoliert, und Konsistenz kann erreicht werden, solange die Atomarität gewährleistet ist. Bei Parallelität müssen Atomarität und Isolation gewährleistet sein, um die Konsistenz sicherzustellen. Probleme bei gleichzeitigen Datenbanktransaktionen Wenn die Transaktionsisolation nicht berücksichtigt wird, können die folgenden Probleme auftreten:
Exklusive Sperre, gemeinsame Sperre Exklusive Sperre, auch als X-Sperre bekannt, Schreibsperre. Gemeinsam genutztes Schloss, auch als S-Schloss bekannt, Leseschloss. Die Beziehung zwischen Lese-/Schreibsperren ist wie folgt:
Das heißt, die Beziehung zwischen Lese- und Schreibsperren kann wie folgt zusammengefasst werden: Mehrfaches Lesen und einmaliges Schreiben Isolationsstufe von Transaktionen Bei Transaktionen gibt es mehrere Isolationsebenen:
Implementierung von Isolationsebenen in MySQL Der obige Inhalt erläutert einige Konzepte der Datenbanktheorie. In Datenbanken wie MySQL und ORACLE werden sie jedoch aus Leistungsgründen nicht vollständig gemäß den oben vorgestellten Theorien implementiert. MVCC Multi-Version Concurrency Control (MVCC) ist eine Methode zur Implementierung von Isolationsebenen in MySQL basierend auf der Theorie optimistischer Sperren. Sie wird zur Implementierung von Read-Commit- und Repeatable-Read-Isolationsebenen verwendet. Implementierung (Isolationsebene ist wiederholbares Lesen) Bevor wir über die Implementierung sprechen, stellen wir zwei Konzepte vor:
In MySQL werden nach jedem Datensatz in der Tabelle zwei Felder hinzugefügt: Versionsnummer erstellen: Beim Erstellen einer Datenzeile wird die aktuelle Systemversionsnummer als Erstellungsversionsnummer zugewiesen. Versionsnummer löschen: Beim Löschen einer Datenzeile wird die aktuelle Systemversionsnummer als Löschversionsnummer vergeben WÄHLEN Für das Lesen der Daten während der Auswahl gilt die Regel: Die Erstellungsversionsnummer <= die aktuelle Transaktionsversionsnummer und die Löschversionsnummer ist leer oder > die aktuelle Transaktionsversionsnummer. Die Erstellungsversionsnummer <= aktuelle Transaktionsversionsnummer stellt sicher, dass die abgerufenen Daten keine Daten enthalten, die in später gestarteten Transaktionen erstellt wurden. Aus diesem Grund sind die nachträglich hinzugefügten Daten im ersten Beispiel nicht vorhanden. Die Löschversionsnummer ist leer oder > der aktuellen Transaktionsversionsnummer. Dadurch wird sichergestellt, dass die Daten zumindest vor dem Start der Transaktion nicht gelöscht wurden und es sich um Daten handelt, die ausgecheckt werden sollten. EINFÜGEN Beim Einfügen ist im Feld Erstellungsversionsnummer die aktuelle Systemversionsnummer zuzuweisen. AKTUALISIEREN Fügen Sie einen neuen Datensatz ein, speichern Sie die aktuelle Transaktionsversionsnummer als Zeilenerstellungsversionsnummer und speichern Sie die aktuelle Transaktionsversionsnummer in der ursprünglich gelöschten Zeile. Tatsächlich wird das Update hier durch Löschen und Einfügen implementiert. LÖSCHEN Beim Löschen wird dem Feld „Löschversionsnummer“ die aktuelle Systemversionsnummer zugewiesen, um anzugeben, in welcher Transaktion die Datenzeile gelöscht wird, auch wenn die Daten beim Ausführen des Commits nicht tatsächlich gelöscht werden. Die Daten werden nicht gefunden, auch wenn sie entsprechend der Auswahlregel geöffnet werden. Löst MVCC wirklich das Phantomlesen? Aus unseren ersten Testbeispielen und der oben genannten theoretischen Unterstützung geht hervor, dass das Phantomleseproblem durch MVCC in MySQL gelöst wurde. Da serielles Lesen sinnlos erscheint, testen wir mit Zweifeln weiter. Daten vor dem Test:
Basierend auf den obigen Ergebnissen erwarten wir das folgende Ergebnis:
Tatsächlich ist unsere Erfahrung jedoch: Ursprünglich hatten wir gehofft, die Abteilung der ersten Daten in „Finanzen“ ändern zu können, letztendlich wurden jedoch beide Daten geändert. Dieses Ergebnis zeigt uns, dass die wiederholbare Leseisolationsebene von MySQL das Problem der Phantomlesevorgänge nicht vollständig löst, jedoch das Phantomleseproblem beim Lesen von Daten löst. Bei Änderungsvorgängen besteht jedoch weiterhin das Phantomleseproblem. Dies bedeutet, dass die MVCC-Lösung für Phantomlesevorgänge nicht gründlich ist. Snapshot-Lesen und aktuelles Lesen Wenn die oben beschriebene Situation eintritt, müssen wir wissen, warum sie auftritt. Nachdem ich einige Informationen konsultiert hatte, stellte ich fest, dass es sich bei den von uns gelesenen Daten auf RR-Ebene zwar aufgrund des MVCC-Mechanismus um historische Daten und nicht um die neuesten Daten in der Datenbank handeln kann, die Daten auf RR-Ebene jedoch wiederholbar sind. Diese Methode zum Lesen historischer Daten wird als Snapshot-Lesen bezeichnet, und die Methode zum Lesen der neuesten Version der Datenbank wird als aktuelles Lesen bezeichnet. Snapshot auswählen lesen Beim Ausführen einer Auswahloperation führt InnoDB standardmäßig einen Snapshot-Lesevorgang durch und zeichnet das Ergebnis dieser Auswahl auf. Die Daten dieses Snapshots werden in nachfolgenden Auswahlvorgängen zurückgegeben. Selbst wenn andere Transaktionen festgeschrieben werden, hat dies keine Auswirkungen auf die Daten der aktuellen Auswahl, sodass ein wiederholbares Lesen erreicht wird. Der Snapshot wird generiert, wenn select zum ersten Mal ausgeführt wird. Das heißt, angenommen, A startet eine Transaktion und führt dann keine Operationen aus. Zu diesem Zeitpunkt fügt B ein Datenelement ein und übergibt es. Zu diesem Zeitpunkt führt A select aus, dann enthalten die zurückgegebenen Daten die von B hinzugefügten Daten. Es spielt keine Rolle, ob anschließend andere Transaktionen festgeschrieben werden, da der Snapshot generiert wurde und nachfolgende Auswahlen auf dem Snapshot basieren. Aktueller Messwert Für Vorgänge, die Daten ändern (Aktualisieren, Einfügen, Löschen), wird der aktuelle Lesemodus verwendet. Beim Ausführen dieser Vorgänge werden die neuesten Datensätze gelesen und sogar von anderen Transaktionen übermittelte Daten können abgefragt werden. Angenommen, Sie möchten einen Datensatz aktualisieren, aber die Daten wurden gelöscht und in einer anderen Transaktion festgeschrieben. Wenn Sie ihn aktualisieren, tritt ein Konflikt auf. Daher müssen Sie beim Aktualisieren die neuesten Daten kennen. Genau aus diesem Grund ist die oben getestete Situation eingetreten. Das aktuelle Lesen von Select muss manuell gesperrt werden: Wählen Sie * aus der Tabelle, wo? Im Freigabemodus sperren; Wählen Sie * aus der Tabelle, wobei ? für die Aktualisierung steht; Es gibt ein Problem zu erklären Zu Beginn des Tests dachte ich, dass die Verwendung der Begin-Anweisung dazu dient, eine Transaktion zu starten. Im zweiten Test oben wurden die neu hinzugefügten Daten von Transaktion 2 in Transaktion 1 gefunden, da Transaktion 1 zuerst gestartet wurde. Zu diesem Zeitpunkt dachte ich, dass dies nicht mit den Auswahlregeln im vorherigen MVCC übereinstimmte, also führte ich den folgenden Test durch: SELECT * FROM information_schema.INNODB_TRX //Wird verwendet, um die aktuell ausgeführte Transaktion abzufragen Es ist ersichtlich, dass eine Transaktion nicht wirklich gestartet wird, wenn Sie nur die Begin-Anweisung ausführen. Fügen Sie als Nächstes nach „begin“ eine Select-Anweisung hinzu: Daher ist es wichtig zu verstehen, dass eine Transaktion erst dann tatsächlich eröffnet wird, wenn Vorgänge wie das Hinzufügen, Löschen, Ändern und Überprüfen der Daten durchgeführt wurden. So lösen Sie Phantom-Reads Offensichtlich kann die wiederholbare Leseisolationsebene das Problem des Phantomlesens nicht vollständig lösen. Wenn wir Phantomlesen in unserem Projekt lösen müssen, gibt es zwei Möglichkeiten:
Tatsächlich werden die beiden oben genannten Methoden in vielen Projekten nicht verwendet. Die Leistung des serialisierten Lesens ist zu schlecht, und tatsächlich ist das Phantomlesen für uns oft völlig akzeptabel. Zusammenfassen Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM. Das könnte Sie auch interessieren:
|
<<: Docker installiert und führt den RabbitMQ-Beispielcode aus
>>: Detaillierte Erklärung zur Installation und Verwendung von Vue-Router
In diesem Artikel wird der spezifische Code von j...
Vorwort Um den Unterschied zwischen dem Hinzufüge...
Kapitel 1 Installation des Quellcodes Die Install...
Vorwort Was ist eine langsame Abfrage und wie kan...
Eine kurze Analyse von rem Zunächst einmal ist re...
1 / Kopieren Sie die Webprojektdateien direkt in ...
Nginx (Engine x) ist ein leistungsstarker HTTP- u...
Nachdem die Systemzeit mit Java ermittelt und in ...
Ich habe heute Redis installiert und es sind eini...
In diesem Artikel finden Sie den spezifischen Cod...
Das MySQL-Entwicklungsteam hat am 14. Oktober 201...
Wenn der Pfad nach dem Domänennamen auf andere Ve...
In diesem Artikelbeispiel wird der spezifische Co...
Laut dem Datenanalyseunternehmen Net Market Share...
Vorwort Dieser Artikel zielt darauf ab, die langw...