Aurora MySQL-Isolierungsstufen - Amazon Aurora

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Aurora MySQL-Isolierungsstufen

Im Folgenden erfahren Sie, wie DB-Instances in einem Aurora MySQL-Cluster die Datenbankeigenschaft „Isolation“ implementieren. Dieses Thema erläutert, wie das Standardverhalten von Aurora MySQL einen Ausgleich zwischen strenger Konsistenz und hoher Leistung sucht. Mithilfe dieser Informationen können Sie entscheiden, wann je nach den Eigenschaften Ihres Workloads die Standardeinstellungen geändert werden sollten.

Verfügbare Isolierungsstufen für Writer-Instances

Sie können die Isolierungsstufen REPEATABLE READ, READ COMMITTED, READ UNCOMMITTED und SERIALIZABLE für die primäre Instance eines Aurora MySQL DB-Clusters verwenden. Diese Isolierungsstufen funktionieren in Aurora MySQL genauso wie in RDS for MySQL.

Isolierungsstufe REPEATABLE READ für Reader-Instances

Standardmäßig verwenden als schreibgeschützte Aurora-Replicas konfigurierte Aurora MySQL-DB-Instances die Isolierungsstufe REPEATABLE READ. Diese DB-Instances ignorieren alle SET TRANSACTION ISOLATION LEVEL-Anweisungen und verwenden weiterhin die Isolierungsstufe REPEATABLE READ.

Isolierungsstufe READ COMMITTED für Reader-Instances

Wenn Ihre Anwendung schreibintensive Workloads auf der primären Instance und lang andauernde Abfragen auf den Aurora-Replicas beinhaltet, kann es zu erheblichen Bereinigungsverzögerungen kommen. Eine Bereinigungsverzögerung tritt auf, wenn die interne Garbage Collection von lang andauernden Abfragen blockiert wird. Das Symptom, das Sie sehen, ist ein hoher Wert für history list length in der Ausgabe des SHOW ENGINE INNODB STATUS-Befehls. Sie können diesen Wert anhand der RollbackSegmentHistoryListLength-Metrik in CloudWatch überwachen. Eine erhebliche Bereinigungsverzögerung kann die Effektivität sekundärer Indizes reduzieren und zu einer geringeren allgemeinen Abfrageleistung führen sowie Speicherplatz verschwenden.

Wenn diese Probleme bei Ihnen auftreten, können Sie mit einer Aurora MySQL-Konfigurationseinstellung auf Sitzungsebene, aurora_read_replica_read_committed, die Isolierungsstufe READ COMMITTED für Aurora-Replicas verwenden. Die Verwendung dieser Einstellung kann Verlangsamungen sowie die Verschwendung von Speicherplatz durch lang andauernde Abfragen reduzieren, während Transaktionen Ihre Tabellen modifizieren.

Wie empfehlen, dass Sie sich mit dem spezifischen Aurora MySQL-Verhalten der READ COMMITTED-Isolierung gut vertraut machen, bevor Sie diese Einstellung verwenden. Das Aurora-Replica READ COMMITTED-Verhalten entspricht dem ANSI SQL-Standard. Die Isolierung ist jedoch weniger strikt als bei dem typischen MySQL READ COMMITTED-Verhalten, mit dem Sie möglicherweise vertraut sind. So kann es etwa zu abweichenden Ergebnissen einer Abfrage unter READ COMMITTED auf einem Aurora MySQL-Lesereplikat und für dieselbe Abfrage unter READ COMMITTED auf der primären Aurora MySQL-Instance oder auf RDS für MySQL kommen. Sie können die aurora_read_replica_read_committed-Einstellung für Anwendungsfälle wie einen umfassenden Bericht über eine sehr große Datenbank verwenden. Für kurze Abfragen mit kleinen Ergebnissätzen, bei denen es auf Präzision und Wiederholbarkeit ankommt, sollten Sie sie eher nicht verwenden.

Die READ COMMITTED-Isolierungsstufe ist nicht für Sitzungen innerhalb eines sekundären Clusters in einer globalen Aurora-Datenbank verfügbar, die die Schreibweiterleitungsfunktion verwenden. Informationen zur Schreibweiterleitung finden Sie unter Verwenden der Schreibweiterleitung in einer Amazon Aurora globalen Datenbank.

Verwenden von READ COMMITTED für Reader

Um die Isolierungsstufe READ COMMITTED für Aurora-Replicas zu aktivieren, setzen Sie die Konfigurationseinstellung aurora_read_replica_read_committed auf ON. Verwenden Sie diese Einstellung auf Sitzungsebene bei Verbindung zu einer spezifischen Aurora-Replica. Führen Sie dazu die folgenden SQL-Befehle aus:

set session aurora_read_replica_read_committed = ON; set session transaction isolation level read committed;

Sie können diese Konfigurationseinstellung temporär verwenden, um interaktive einmalige Abfragen durchzuführen. Sie können auch eine Berichts- oder Datenanalyseanwendung ausführen, die von der Isolierungsstufe READ COMMITTED profitiert, wobei die Standards für andere Anwendungen unverändert bleiben.

Wenn die aurora_read_replica_read_committed-Einstellung aktiviert ist, geben Sie mit dem SET TRANSACTION ISOLATION LEVEL-Befehl die Isolierungsstufe für die jeweiligen Transaktionen an.

set transaction isolation level read committed;

Unterschiede beim Verhalten von READ COMMITTED auf Aurora-Replikaten

Die aurora_read_replica_read_committed-Einstellung stellt die Isolierungsstufe READ COMMITTED für eine Aurora-Replica zur Verfügung, mit einem Konsistenzverhalten, das für lang andauernde Transaktionen optimiert ist. Die Isolierungsstufe READ COMMITTED auf Aurora-Replicas bietet eine weniger strikte Isolierung als auf primären Aurora-Instances. Aktivieren Sie daher diese Einstellung nur auf Aurora-Replicas, wenn Sie wissen, dass für Ihre Abfragen bestimmte Arten inkonsistenter Ergebnisse akzeptabel sind.

Bei Ihren Abfragen können bestimmte Arten von Anomalien auftreten, wenn die aurora_read_replica_read_committed-Einstellung aktiviert ist. Dabei sollten Sie besonders zwei Arten von Anomalien verstehen und in Ihrem Anwendungscode berücksichtigen. Eine nicht-wiederholbarer Lesevorgang tritt auf, wenn eine andere Transaktion ein Commit durchführt, während Ihre Abfrage läuft. Eine lang andauernde Abfrage kann an ihrem Anfang andere Daten sehen als an ihrem Ende. Eine Phantom-Lesevorgang tritt auf, wenn andere Transaktionen dazu führen, dass bestehende Zeilen umorganisiert werden, während Ihre Abfrage läuft, und dass dadurch eine oder mehrere Zeilen von Ihrer Abfrage zweimal gelesen werden.

Phantom-Lesevorgänge können in Ihren Abfragen zu inkonsistenten Zeilenanzahlen führen. Nicht-wiederholbare Lesevorgänge können auch zur Ausgabe unvollständiger oder inkonsistenter Ergebnisse führen. Nehmen Sie beispielsweise an, eine Join-Operation bezieht sich auf Tabellen, die gleichzeitig von SQL-Anweisungen wie INSERT oder DELETE modifiziert werden. In diesem Fall kann es sein, dass die Join-Abfrage eine Zeile aus einer Tabelle liest, aber nicht die entsprechende Zeile aus einer anderen Tabelle.

Der ANSI SQL-Standard lässt beide Verhaltensweisen für die Isolationsstufe READ COMMITTED zu. Diese Verhaltensweisen unterscheiden sich jedoch von der typischen MySQL-Implementierung von READ COMMITTED. Prüfen Sie daher vor der Aktivierung der aurora_read_replica_read_committed-Einstellung bestehenden SQL-Code darauf, ob er im Rahmen des lockereren Konsistenzmodell so funktioniert wie erwartet.

Zeilenanzahlen und andere Ergebnisse sind auf der Isolationsstufe READ COMMITTED bei Aktivierung dieser Einstellung möglicherweise nicht streng konsistent. Sie sollten diese Einstellung daher typischerweise nur aktivieren, wenn Sie analytische Abfragen ausführen, die große Datenmengen aggregieren und für die keine absolute Präzision erforderlich ist. Wenn Sie nicht solche lang andauernden Abfragen zusammen mit schreibintensiven Workloads verwenden, benötigen Sie die aurora_read_replica_read_committed-Einstellung wahrscheinlich nicht. Ohne die Kombination aus lang andauernden Abfragen und schreibintensiven Workloads sind Probleme mit der Länge der Verlaufsliste unwahrscheinlich.

Beispiel Abfragen mit Isolationsverhalten für READ COMMITTED auf Aurora-Replicas

Das folgende Beispiel zeigt, wie READ COMMITTED-Abfragen auf einer Aurora-Replica möglicherweise nicht wiederholbare Ergebnisse ausgeben, wenn Transaktionen gleichzeitig die zugehörigen Tabellen modifizieren. Die Tabelle BIG_TABLE enthält eine Million Zeilen vor Beginn jeder Anfrage. Andere DML- (Data Manipulation Language) Anweisungen fügen Zeilen hinzu, entfernen oder ändern sie.

Die Abfragen auf der primären Aurora-Instance bei Isolierungsstufe READ COMMITTED führen zu vorhersehbaren Ergebnissen. Die Overheadlast, die damit verbunden ist, den Consistent-Lesevorgang für die gesamte Dauer einer lang andauernden Abfrage aufrechtzuerhalten, kann später zum umfangreichen Garbage Collection führen.

Die Abfragen auf der Aurora-Replica bei Isolierungsstufe READ COMMITTED sind so optimiert, dass dieses Garbage-Collection-Overhead minimiert wird. Dies führt aber andererseits dazu, dass die Ergebnisse abweichen können, wenn die Abfragen auf Zeilen stoßen, die von Transaktionen, die während der Ausführung der Abfrage Commits durchführen, hinzugefügt, entfernt oder umorganisiert werden. Die Abfragen können diese Zeilen berücksichtigen, müssen dies aber nicht tun. Zu Demonstrationszwecken prüfen die Abfragen nur die Anzahl der Zeilen in der Tabelle mithilfe der COUNT(*)-Funktion.

Zeit DML-Anweisung auf der primären Aurora-Instance Abfrage auf der primären Aurora-Instance mit READ COMMITTED Abfrage auf einer Aurora-Replica mit READ COMMITTED
T1 INSERT INTO big_table SELECT * FROM other_table LIMIT 1000000; COMMIT;
T2 Q1: SELECT COUNT(*) FROM big_table; Q2: SELECT COUNT(*) FROM big_table;
T3 INSERT INTO big_table (c1, c2) VALUES (1, 'one more row'); COMMIT;
T4 Wenn Q1 jetzt beendet wird, ist das Ergebnis 1.000.000. Wenn Q2 jetzt beendet wird, ist das Ergebnis 1.000.000 oder 1.000.001.
T5 DELETE FROM big_table LIMIT 2; COMMIT;
T6 Wenn Q1 jetzt beendet wird, ist das Ergebnis 1.000.000. Wenn Q2 jetzt beendet wird, ist das Ergebnis 1.000.000, 1.000.001, 999.999 oder 999.998.
T7 UPDATE big_table SET c2 = CONCAT(c2,c2,c2); COMMIT;
T8 Wenn Q1 jetzt beendet wird, ist das Ergebnis 1.000.000. Wenn Q2 jetzt beendet wird, ist das Ergebnis 1.000.000, 1.000.001, 999.999 oder möglicherweise eine höhere Zahl.
T9 Q3: SELECT COUNT(*) FROM big_table; Q4: SELECT COUNT(*) FROM big_table;
T10 Wenn Q3 jetzt beendet wird, ist das Ergebnis 999.999. Wenn Q4 jetzt beendet wird, ist das Ergebnis 999.999.
T11 Q5: SELECT COUNT(*) FROM parent_table p JOIN child_table c ON (p.id = c.id) WHERE p.id = 1000; Q6: SELECT COUNT(*) FROM parent_table p JOIN child_table c ON (p.id = c.id) WHERE p.id = 1000;
T12 INSERT INTO parent_table (id, s) VALUES (1000, 'hello'); INSERT INTO child_table (id, s) VALUES (1000, 'world'); COMMIT;
T13 Wenn Q5 jetzt beendet wird, ist das Ergebnis 0. Wenn Q6 jetzt beendet wird, ist das Ergebnis 0 oder 1.

Wenn die Abfragen schnell abgeschlossen sind, bevor andere Transaktionen DML-Anweisungen und Commits durchführen, sind die Ergebnisse vorhersehbar und zwischen der primären Instance und der Aurora-Replica identisch. Sehen wir uns die Verhaltensunterschiede im Detail an, beginnend mit der ersten Abfrage.

Die Ergebnisse für Q1 sind äußerst vorhersehbar, weil READ COMMITTED auf der primären Instance ein starkes Konsistenzmodell ähnlich der Isolierungsstufe REPEATABLE READ verwendet.

Die Ergebnisse für Q2 können je nachdem, welche Transaktionen während der Ausführung der Abfrage Commits durchführen, abweichen. Nehmen wir beispielsweise an, dass andere Transaktionen DML-Anweisungen und Commits durchführen, während die Abfragen laufen. In diesem Fall kann es sein, dass die Abfrage auf der Aurora-Replica mit Isolierungsstufe READ COMMITTED die Änderungen berücksichtigt oder nicht. Die Zeilenanzahlen sind dabei nicht in der gleichen Weise vorhersagbar wie bei Isolierungsstufe REPEATABLE READ. Sie sind auch nicht so vorhersagbar wie Abfragen mit Isolierungsstufe READ COMMITTED auf der primären Instance oder auf einer RDS für MySQL-Instance.

Die UPDATE-Anweisung bei T7 ändert die Anzahl der Zeilen in der Tabelle nicht. Durch die Änderung der Länge einer Spalte mit variabler Länge kann diese Anweisung jedoch dazu führen, dass Zeilen intern umorganisiert werden. Eine lang andauernde READ COMMITTED-Transaktion kann zunächst die alte Version einer Zeile und später im Rahmen derselben Transaktion eine neue Version derselben Zeile sehen. Die Abfrage kann auch die alte und die neue Version der Zeile überspringen, so dass die Anzahl der Zeilen von der erwarteten abweicht.

Die Ergebnisse von Q5 und Q6 können identisch oder leicht abweichend sein. Abfrage Q6 auf der Aurora-Replica unter READ COMMITTED kann, muss aber nicht, die neuen Zeilen sehen, für die während der Dauer der Abfrage ein Commit durchgeführt wird. Möglicherweise sieht sie auch die Zeile aus einer, aber nicht aus der anderen Tabelle. Wenn die Join-Abfrage keine übereinstimmende Zeile in beiden Tabellen findet, gibt sie die Anzahl 0 zurück. Wenn die Abfrage beide neuen Zeilen in PARENT_TABLE und CHILD_TABLE findet, gibt sie die Anzahl 1 zurück. In einer lang andauernden Anfrage können die Lookups aus den verbundenen Tabellen zu weit auseinanderliegenden Zeitpunkten stattfinden.

Anmerkung

Diese Verhaltensunterschiede hängen davon ab, wann für Transaktionen Commits durchgeführt werden, und wann die Abfragen die zugrunde liegenden Tabellenzeilen abfragen. Daher sind solche Unterschiede am wahrscheinlichsten in Berichtsabfragen, die mehrere Minuten oder Stunden dauern, und die auf Aurora-Clustern durchgeführt werden, die gleichzeitig OLTP-Transaktionen ausführen. Dies sind die Arten gemischter Workloads, die am meisten von der Isolierungsstufe READ COMMITTED auf Aurora-Replicas profitieren.