Wo speichert InnoDB Transaktionsdaten, bevor sie festgeschrieben werden?


12

Ich habe einige Tests mit READ_COMMITTEDund READ_UNCOMMITTEDzu Hause mit der JDBC-Technologie durchgeführt.

Ich sehe, dass READ_UNCOMMITTEDtatsächlich nicht festgeschriebene Daten gelesen werden können, z. B. Daten von einer Transaktion, die noch nicht festgeschrieben wurde (könnte eine UPDATE-Abfrage durchführen).

Fragen

  • Wo werden nicht festgeschriebene Daten gespeichert, sodass eine READ_UNCOMMITTEDTransaktion nicht festgeschriebene Daten aus einer anderen Transaktion lesen kann?
  • Warum kann eine READ_COMMITTEDTransaktion nicht festgeschriebene Daten lesen, dh einen "Dirty Read" durchführen? Welcher Mechanismus erzwingt diese Einschränkung?

Antworten:


11

" Wo werden nicht festgeschriebene Daten gespeichert, sodass eine READ_UNCOMMITTED-Transaktion nicht festgeschriebene Daten aus einer anderen Transaktion lesen kann? "

Die neuen nicht festgeschriebenen Datensatzversionen (Clustered PK) werden als "aktuelle" Version des Datensatzes auf Seite behandelt. Sie können also im Pufferpool und / oder im Tablespace (zB tablename.ibd) gespeichert werden. Transaktionen , die dann müssen einen Snapshot / Blick in etwas anderes als READ-UNCOMMITTED bauen, bedarf eine vorherige Version der Zeile (nach der Verlaufsliste) mit den Aufhebungsaufzeichnungen (gespeichert in dem konstruieren System Tabellen ). Beim Lesen des nicht festgeschriebenen Datensatzes muss InnoDB möglicherweise auch einige nicht festgeschriebene sekundäre Indexdatensätze aus dem Änderungspuffer lesen und anwenden, bevor der Datensatz dem Benutzer wieder angezeigt wird .

Dieses Verhalten kann Rollbacks in InnoDB relativ teuer machen. Dies ist der große Faktor, der auch zu potenziellen Leistungsproblemen bei lang laufenden Leerlauftransaktionen mit aktualisierten Datensätzen führen kann, da diese Transaktionen Bereinigungsvorgänge blockieren und die Verlaufsliste alter Datensatzversionen wächst und die UNDO-Datensätze zum Wiederherstellen dieser alten Versionen erforderlich sind On-Demand wird weiter wachsen. Es verlangsamt neue Transaktionen, die eine ältere / festgeschriebene Version des Datensatzes lesen müssen, da sie eine immer längere Verlaufsliste - eine einfach verknüpfte Liste von UNDO-Datensätzen - durchlaufen und mehr Arbeit für die Rekonstruktion leisten müssen die alte Version des Datensatzes. Sie verwenden also am Ende viele CPU-Zyklen (ganz zu schweigen von internen Sperrprimitiven: Mutexe, rw_locks, Semaphoren usw.).

Hoffentlich macht das Sinn? :) :)

Als FYI können Sie in MySQL 5.7 den UNDO-Tabellenbereich verschieben und sich aus dem Systemtabellenbereich abmelden und diese automatisch abschneiden lassen. Sie können sehr groß werden, wenn Sie eine lange laufende Transaktion haben, die Bereinigungsvorgänge verhindert, was zu einer sehr langen und ständig wachsenden Länge der Verlaufsliste führt. Das Speichern im Systemtabellenbereich war die häufigste Ursache für eine große / wachsende ibdata1-Datei, die wiederum nicht abgeschnitten / verkleinert / gesaugt werden kann, um diesen Speicherplatz später zurückzugewinnen.


4

Du hast gefragt

Wo werden nicht festgeschriebene Daten gespeichert, sodass eine READ_UNCOMMITTED-Transaktion nicht festgeschriebene Daten aus einer anderen Transaktion lesen kann?

Um Ihre Frage zu beantworten, müssen Sie wissen, wie die InnoDB-Architektur aussieht.

Das folgende Bild wurde vor Jahren von Percona CTO Vadim Tkachenko erstellt

InnoDB-Architektur

Laut MySQL-Dokumentation am InnoDB-Transaktionsmodell und zum Sperren

Ein COMMIT bedeutet, dass die in der aktuellen Transaktion vorgenommenen Änderungen dauerhaft sind und für andere Sitzungen sichtbar werden. Eine ROLLBACK-Anweisung bricht dagegen alle durch die aktuelle Transaktion vorgenommenen Änderungen ab. Sowohl COMMIT als auch ROLLBACK geben alle InnoDB-Sperren frei, die während der aktuellen Transaktion festgelegt wurden.

Da COMMIT und ROLLBACK die Sichtbarkeit von Daten regeln, müssten READ COMMITTED und READ UNCOMMITTED auf Strukturen und Mechanismen angewiesen sein, die Änderungen aufzeichnen

  1. Rollback-Segmente / Leerzeichen rückgängig machen
  2. Protokolle wiederholen
  3. Lückensperren für die beteiligten Tabellen

Rollback-Segmente und Undo Space würden wissen, wie geänderte Daten aussehen, bevor Änderungen angewendet werden. Redo Logs würde wissen, welche Änderungen vorwärts gerollt werden müssen, damit die Daten aktualisiert werden.

Du hast auch gefragt

Warum kann eine READ_COMMITTED-Transaktion nicht festgeschriebene Daten lesen, dh einen "Dirty Read" durchführen? Welcher Mechanismus erzwingt diese Einschränkung?

Protokolle wiederholen, Leerzeichen rückgängig machen und gesperrte Zeilen kommen ins Spiel. Sie müssen auch den InnoDB- Pufferpool berücksichtigen (wo Sie schmutzige Seiten mit innodb_max_dirty_pages_pct , innodb_buffer_pool_pages_dirty und innodb_buffer_pool_bytes_dirty messen können ).

Vor diesem Hintergrund würde READ COMMITTED wissen, wie Daten dauerhaft aussehen. Daher müssen Sie nicht nach schmutzigen Seiten suchen, die nicht festgeschrieben wurden. READ COMMITED wäre nichts anderes als ein Dirty Read, der festgeschrieben wurde. READ UNCOMMITTED hätte weiterhin wissen müssen, welche Zeilen gesperrt werden sollen und welche Redo-Protokolle gelesen oder ignoriert wurden, um die Daten sichtbar zu machen.

Lesen Sie das InnoDB-Transaktionsmodell und das Sperren , um das Sperren von Zeilen zum Verwalten der Isolation vollständig zu verstehen


1
Zunächst einmal vielen Dank für Ihre Antwort und Änderung meines Beitrags ... Vor einem COMMIT sind Änderungen für andere Benutzer des Systems nicht sichtbar? Hier bedeutet Benutzer wörtlich eine Transaktion, oder? Wo kann diese Isolationsstufe diese Daten lesen, da READ UNCOMMITTED nicht festgeschriebene Daten lesen kann? Könnte es mehr als eine Quelle für nicht festgeschriebene Daten für ein bestimmtes Datenelement in einer Datenbank geben? Wenn ja, welche nicht festgeschriebenen Daten werden dann gelesen?
Shuzheng
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.