2 Punkte von GN⁺ 2025-04-30 | 1 Kommentare | Auf WhatsApp teilen
  • In Jepsen-Tests wurde ein Fall bestätigt, in dem Amazon RDS for PostgreSQL Multi-AZ-Cluster Snapshot Isolation nicht einhalten – die stärkste Isolationsstufe bezogen auf alle Knoten
  • Die Hauptursache ist, dass die Reihenfolge, in der Transaktionen auf dem Primary sichtbar werden, durch In-Memory-Locks bestimmt wird, während Secondaries der WAL-Reihenfolge folgen; diese beiden Reihenfolgen können auseinanderlaufen
  • Auch ohne Fehlerinjektion oder Failover traten unter Bedingungen mit gp3-Storage und db.m6id.large-Instanzen bei etwa 150 Write TPS / 1600 Read-only TPS alle paar Minuten G-nonadjacent Cycles auf
  • Die Anomalie entspricht einem Long Fork und trat in allen getesteten Versionen von PostgreSQL 13.15 bis 17.4 auf, die AWS unterstützt; Short Fork/Write Skew wurde nicht beobachtet
  • Bei sicherheitskritischen Transaktionen kann die Ausführungsreihenfolge bei Nutzung von Read-only-Secondaries unterschiedlich erscheinen; daher sollte geprüft werden, nur den Writer Endpoint zu verwenden oder mindestens einen Write einzuschließen

Update zur Ursache von Long Fork

  • Sergey Melnik von AWS sowie die HN-Kommentatoren matashii und Ants Aasma haben die Ursache von Long Fork in PostgreSQL-Clustern identifiziert
  • Ein PostgreSQL-Primary bestimmt die Reihenfolge, in der Transaktionen sichtbar werden, über In-Memory-Locks
  • Ein Secondary macht Transaktionen in der Reihenfolge sichtbar, in der sie im Write-Ahead Log (WAL) stehen
  • Wenn Lock-Reihenfolge und WAL-Reihenfolge voneinander abweichen, können Primary und Secondary die scheinbare Reihenfolge von Transaktionen unterschiedlich sehen
  • Dieses Verhalten wurde 2013 in einem Beitrag auf der PostgreSQL-Mailingliste behandelt, und Melnik verfasste im AWS-Blog einen Beitrag zur Transaction Visibility in PostgreSQL-Clustern und Read Replicas
  • Jepsen empfiehlt AWS und PostgreSQL, dieses Problem zu dokumentieren und an einer Behebung zu arbeiten

Isolationsstufen und Architektur von RDS for PostgreSQL

  • PostgreSQL ist eine universelle Open-Source-SQL-Datenbank und bietet per MVCC drei Transaktions-Isolationsstufen
    • Read Uncommitted und Read Committed verhalten sich beide als Read Committed
    • Repeatable Read bietet tatsächlich nicht Repeatable Read, sondern Snapshot Isolation
    • Serializable bietet Serializability
  • Amazon RDS for PostgreSQL ist ein AWS-Service für verwaltete PostgreSQL-Cluster
    • Er automatisiert Provisioning, Storage-Verwaltung, Replikation, Backups, Upgrades und mehr
    • Multi-AZ Deployments verteilen Datenbankknoten über mehrere Availability Zones, um die Wahrscheinlichkeit korrelierter Ausfälle zu reduzieren
    • RDS nutzt synchrone Replikation, sodass eine Antwort erst erfolgt, nachdem die Transaktionsdauerhaftigkeit sowohl auf dem Primary als auch auf mindestens einer Secondary-Instanz sichergestellt ist
  • Nutzern werden zwei URLs bereitgestellt, die das PostgreSQL Wire Protocol sprechen
    • Primary Endpoint: für Read-write-Transaktionen
    • Reader Endpoint: für Read-only-Transaktionen
  • Der Primary Endpoint unterstützt alle PostgreSQL-Isolationsstufen, Secondaries unterstützen jedoch kein Serializable
  • Die stärkste über alle Knoten nutzbare Isolationsstufe ist Snapshot Isolation, die PostgreSQL Repeatable Read nennt

Testdesign

  • Jepsen passte seine Testbibliothek für PostgreSQL an Amazon RDS for PostgreSQL an und verwendete ein kleines Wrapper-Programm
  • Für jede Testrunde wurde über die AWS-CreateDBCluster-API ein RDS-Cluster bereitgestellt
    • Storage: gp3
    • Instanz: db.m6id.large
  • Ein EC2-Knoten für die Testausführung wurde gestartet und mit dem Main Endpoint sowie dem Read-only Endpoint des RDS-Clusters versorgt
  • Es gab keine Fehlerinjektion und auch kein ausgelöstes Failover
  • Die Haupt-Workload bestand aus Transaktionen, die Listen eindeutiger Ganzzahlen bearbeiten
    • Jede Liste wird in einer einzelnen Row gespeichert und als TEXT-Feld mit kommaseparierten Werten kodiert
    • Transaktionen lesen Listen per Primary Key oder hängen mit CONCAT eindeutige Ganzzahlen an Listen an
  • Mit dieser Workload kann der Elle Checker Datenflussabhängigkeiten zwischen Transaktionen ableiten und Graph-Cycles finden, um verschiedene Isolationsstufen zu prüfen

Beobachtete G-nonadjacent Cycles

  • Unter normalen Bedingungen und bei mittlerer Parallelität zeigte Amazon RDS for PostgreSQL 17.4 alle paar Minuten G-nonadjacent Cycles
  • Ein zweiminütiger Testlauf führte etwa 150 Write TPS und 1600 Read-only TPS aus und enthielt einen Cycle aus vier Transaktionen
  • Der Beispiel-Cycle besteht aus den vier Transaktionen T1, T2, T3, T4
    • T1 hängte an Row 89 den Wert 9 an und erzeugte die Liste [4 9], die T2 beobachtete
    • T3 hängte an Row 90 den Wert 11 an und erzeugte die Liste [11]
    • T4 hängte an Row 90 den Wert 3 an und las die Ergebnisliste [11, 3], wodurch es die Version von T3 überschrieb
    • T2 beobachtete in Row 89 den Append von T1, sah aber in Row 90 den Append von T3 nicht
    • Umgekehrt beobachtete T4 in Row 90 den Append von T3, verpasste aber in Row 89 den Append von T1
  • Da dieser Cycle nicht benachbarte Read-write Dependencies enthält, ist er ein G-nonadjacent Cycle und damit eine Verletzung von Snapshot Isolation
  • Unter Repeatable Read im Standard-PostgreSQL sollte dieses Verhalten nicht auftreten, und Jepsen konnte es in Standard-PostgreSQL nicht beobachten

Warum dies Snapshot Isolation widerspricht

  • Bei Snapshot Isolation muss jede Transaktion so erscheinen, als würde sie auf einem Datenbank-Snapshot zum Start-Timestamp s arbeiten
  • Die Effekte einer Transaktion werden für andere Transaktionen zu einem späteren Commit-Timestamp c sichtbar
  • Schreibt man die Beobachtungen aus dem Beispiel-Cycle als Timestamp-Beziehungen, ergeben sich Widersprüche
    • Da T2 den Append von T1 gelesen hat, muss der Start von T2 nach dem Commit von T1 liegen: c1 < s2
    • Da T2 den Append von T3 nicht beobachtet hat, gilt: s2 < c3
    • Da T4 T3 überschrieben und beobachtet hat, gilt: c3 < s4
    • Da T4 den Append von T1 nicht beobachtet hat, gilt: s4 < c1
  • Diese Beziehungen können nicht alle gleichzeitig gelten und widersprechen daher dem Timestamp-Modell von Snapshot Isolation

Long Fork und Ergebnisse nach Version

  • Der Cycle ist auch ein Beispiel für Long Fork
    • Die erste und zweite Transaktion bilden einen logischen State-Fork
    • Die dritte und vierte Transaktion bilden den zweiten Fork
    • Die beiden Forks aktualisieren unterschiedliche Rows, beobachten aber die Effekte des jeweils anderen nicht
  • Short Fork, also Write Skew, wurde nicht beobachtet
  • Dieses Ergebnis deutet darauf hin, dass Amazon RDS for PostgreSQL möglicherweise Parallel Snapshot Isolation bietet, eine etwas schwächere Form als Snapshot Isolation
  • G-nonadjacent-Anomalien traten in unterschiedlichen Formen auf, darunter Fälle, die nur durch Write-read Edges verbunden waren, sowie Fälle mit mehr als vier Transaktionen
  • In allen getesteten Versionen, von PostgreSQL 13.15 als ältester von AWS unterstützter Version bis zur neuesten Version 17.4, trat dieselbe Art von Anomalie auf

Was Nutzer prüfen sollten

  • Da Long Fork und andere G-nonadjacent Cycles existieren, garantieren Amazon RDS for PostgreSQL Multi-AZ-Cluster keine Snapshot Isolation
  • In dieser Hinsicht bieten RDS-for-PostgreSQL-Multi-AZ-Cluster schwächere Sicherheitssemantiken als Single-Node-PostgreSQL, das in früheren Jepsen-Tests Strong Snapshot Isolation zu bieten schien
  • Nutzer können prüfen, ob ihre Transaktionsstruktur anfällig für Long Fork ist, oder experimentell verifizieren, ob beabsichtigte Invarianten eingehalten werden
  • Read-Transaktionen können hinsichtlich der Transaktionsausführungsreihenfolge andere Ergebnisse sehen als andere Transaktionen
  • Da die Anomalien offenbar mit Queries gegen Read-only-Secondaries zusammenhängen, könnte Snapshot Isolation möglicherweise mit folgenden Ansätzen wiederhergestellt werden
    • Nur den Writer Endpoint verwenden

      • In alle sicherheitskritischen Transaktionen mindestens einen Write aufnehmen
      • Jepsens Validierung ist ein experimenteller Ansatz; sie kann die Existenz von Bugs nachweisen, aber nicht deren Abwesenheit
      • Dieser Bericht ist nicht das Ergebnis einer detaillierten Untersuchung des Verhaltens von RDS for PostgreSQL, sondern einer vorläufigen Erkundung

1 Kommentare

 
GN⁺ 2025-04-30
Meinungen auf Hacker News
  • Ich wünschte, Texte in der Softwarewelt wären häufiger so: „Amazon RDS for PostgreSQL ist ein Service von Amazon Web Services (AWS), der verwaltete Instanzen von PostgreSQL-Datenbanken bereitstellt. Wir zeigen, dass Amazon RDS for PostgreSQL multi-AZ clusters Snapshot Isolation verletzen, das stärkste Konsistenzmodell, das über alle Endpunkte hinweg unterstützt wird …“
    Direkt, auf den Punkt und ohne Ausschmückung – ähnlich wie die Kommunikation von Forschungsergebnissen in anderen STEM-Bereichen. Früher mochte ich geistreiche Blogposts, die Dinge mit Memes erklärten, aber inzwischen sehne ich mich nach plain und einfachen Texten.

    • In einer früheren Firma gab es einen internen Blog, in dem jeder schreiben und kommentieren konnte; es war nicht verpflichtend und floss überhaupt nicht in Bewertungen ein. Es fühlte sich wie ein Hackathon-Ergebnis an, aber da ich technisches Schreiben mag, habe ich es ziemlich genossen.
      Wenn ich sehr tiefgehende technische Texte schrieb, gab es kaum Likes und Kommentare; ein Staff Engineer meinte sogar, ich solle die Zielgruppe enger fassen. Umgekehrt schrieb ich beim Testen des frühen Kubecost einen Beitrag darüber, dass die Empfehlungen nur geringe Kosteneinsparungen bringen und Performance-Probleme bei Containern verursachen könnten; obwohl der Artikel mit CPU throttling und cgroups ziemlich technisch war, fanden ihn die Leute großartig, sobald ich Memes einbaute.
      Später schrieb ich einen noch trockeneren Beitrag darüber, eine kleine externe Python-Bibliothek in C zu erstellen, per ctypes darauf zuzugreifen und Stack-/Heap-Allokation zu vergleichen; mit Memes erzielte er ein ähnliches Ergebnis. Mir gefällt diese Entwicklung nicht, aber ich weiß auch kaum, wie man sonst ein breiteres Publikum erreicht. Jensen zielte nicht auf diese Leserschaft ab, und das strenge, unverfälschte Schreiben verdient Applaus.
    • Blogposts voller Memes will ich inzwischen wirklich nicht mehr lesen. Besonders oft wird dabei Inhalt, der in einen Absatz passen würde, künstlich aufgeblasen; heutzutage sind Beiträge zu Security-Schwachstellen in dieser Hinsicht oft am schlimmsten.
    • Ich hatte gerade daran gedacht, dass ich das alte Jepsen vermisse. Es war auf ähnliche Weise faktenorientiert und direkt, aber zugleich voller Memes. Der alte Redis-Artikel https://aphyr.com/posts/283-call-me-maybe-redis ist ein gutes Beispiel.
    • Amazon ist dafür bekannt, eine gesunde Kultur des technischen Schreibens zu haben, und nach meiner eigenen Erfahrung war das auch so. Das ist meine persönliche Meinung, nicht die des Unternehmens. Es gibt dazu auch einen öffentlichen Artikel: https://quartr.com/insights/business-philosophy/amazon-s-wri...
  • Es steht weder im Titel noch ist es im Artikel ganz eindeutig, aber dieses Problem ist auf multi-AZ clusters beschränkt, eine relativ neue Funktion von RDS. Das ist etwas anderes als die multi-AZ instances, mit denen viele vertraut sind.
    multi-AZ instances sind die ältere Funktion, bei der die primäre DB synchron auf eine sekundäre DB in einer anderen Availability Zone repliziert wird und RDS bei einem Ausfall der primären auf die sekundäre umschaltet.
    multi-AZ clusters haben zwei sekundäre Knoten, und Transaktionen werden synchron auf mindestens einen davon repliziert. Wenn ein sekundärer Knoten ausfällt oder langsamer wird, ist das robuster als multi-AZ instances; außerdem ist Read-only-Zugriff auf die sekundären Knoten möglich.
    Allerdings steckt in multi-AZ clusters intern vermutlich mehr zusätzliche Magie, die nicht zu den Standardfunktionen von PostgreSQL gehört, und wahrscheinlich sind sie deshalb im Jepsen-Test gescheitert.

    • Interessant ist, warum diese Magie nötig ist. Standard-PostgreSQL unterstützt ebenfalls Quorum Commit, sodass eine solche Konfiguration möglich ist. Mit Patroni kann man einen gleichwertigen multi-AZ cluster bauen, und abgesehen von Bugs passt es die Primary-Promotion so an, dass keine Transaktionen verloren gehen und keine nicht-durable Transaktion sichtbar wird.
      Allerdings gibt es in PostgreSQL noch einen Defekt, der ein ähnliches Problem wie dieses Muster möglich macht. Eine nicht replizierte Transaktion, bei der der Client während des Commits verschwindet, wird sofort sichtbar. Wenn im Beispiel T1 auf einem abgetrennten Leader stattfindet und die Verbindung während des Commits abbricht, T2 ebenfalls auf dem abgetrennten Knoten stattfindet und T3/T4 später auf dem neuen Leader stattfinden, kann man dasselbe Ergebnis sehen. Das passt allerdings nicht gut zu der Aussage, dass in diesem Test kein Fault Injection vorgenommen wurde.
      Korrektur: Ich hatte nicht gesehen, dass der Artikel dieses Muster durch eine abweichende Commit-Reihenfolge zwischen Replikat und primärem Knoten erklärt. Ein bisschen peinlich, weil ich schon einmal vorgestellt habe, wie man dieses Problem behebt.
    • Wenn innerhalb einer multi-AZ instance eine Verletzung der Snapshot Isolation auftritt, frage ich mich, ob sie auch in einer Konfiguration mit mehreren Read Replicas in einer einzigen Region auftreten könnte. Allerdings könnte es sein, dass die Verzögerung in einer multi-AZ-Konfiguration größer ist und sich das Problem deshalb leichter beobachten lässt.
    • Es steht direkt im zweiten Satz des Artikels: „Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation“. Man sollte erwarten dürfen, dass die Leute lesen.
  • Gute Untersuchung. Viele Softwareentwickler kennen heutzutage nicht einmal Transaktionen richtig, geschweige denn die verschiedenen Transaktionsmodelle. Ich habe sogar unter CRUD-Entwicklern, die als „Senior Developer“ bezeichnet werden, Leute gesehen, die von Datenbanktransaktionen überhaupt keine Ahnung hatten.
    Wenn es in der Praxis ein gewisses Traffic-Volumen gibt und die Software nicht triviale Probleme löst, sind Transaktionen und Transaktionsmodelle extrem wichtig für Performance und fehlerfreien Code.
    In einem großen Projekt haben wir zum Beispiel nach umfangreicher Analyse von SQL Servers standardmäßigem Read Committed auf Read Committed Snapshot Isolation umgestellt, und die Lock Contention verschwand weitgehend, was die Nutzer sehr zufrieden machte. Die Software Engineers in diesem Projekt nutzten zwar viele Transaktionen, wussten aber nichts über Transaktionsmodelle oder Locks, bis man ihnen die Grundlagen beibrachte.

    • Das ist nicht nur auf Senior Developer beschränkt. Ich habe auch Systemarchitekten gesehen, die Isolationsstufen nicht kannten, und manche verwechselten die „Consistency“ in ACID mit der „Consistency“ in CAP.
      Da ich hauptsächlich im Retail-Bereich arbeite, sehe ich oft Systeme voller Fehler, die Race Conditions ähneln; umso bedauerlicher ist es, weil solche Isolationsstufen hier sehr helfen könnten.
      Allerdings habe ich solche Fälle vor allem bei Startup-Engineers gesehen; die typischen Oracle-/MSSQL-Entwickler in Großunternehmen schätze ich recht hoch ein, weil bei ihnen zumindest die Grundlagen stimmen.
    • Mangelndes Transaktionsbewusstsein habe ich vor allem in Serverless-/Edge-Umgebungen gesehen. Wenn man es überhaupt Backend-Architektur nennen kann, sind das Orte, an denen alles vollständig von Client-Anforderungen getrieben ist. Datenbankabfragen werden zum Beispiel als React-Hook oder als sequenzielle API-Aufrufe modelliert.
      Ein paar Mal in meiner Karriere habe ich gesehen, dass dieser Ansatz wirklich schlechte Ergebnisse liefert.
    • Bald werden die meisten Softwareentwickler LLM-Müll in Code abschreiben, ohne zu wissen, was tatsächlich passiert. Bei Shopify ist es schon Pflicht, und Microsoft prahlt damit, dass ein Drittel der Software auf diese Weise geschrieben wurde. Wenn es künftig keine Engineering-Jobs mehr geben soll, fragt man sich, wer sich überhaupt noch die Zeit nehmen wird, das zu lernen.
    • Meine Empfehlung an Juniors ist seit zehn Jahren dieselbe: An einem Wochenende ein Buch über SQL-Datenbanken lesen und am nächsten Wochenende ein Buch über die Datenbank, die im aktuellen Projekt verwendet wird. Dann ist die Wahrscheinlichkeit groß, dass man zum Datenbankexperten dieses Projekts wird.
    • Vor ein paar Jahren hatten wir eine ähnliche Situation und haben ein Produkt, das heute etwa 1 Milliarde Dollar Umsatz macht, von Read Committed auf Read Committed Snapshot umgestellt, was die Performance deutlich verbessert hat.
      Bei dieser Umstellung muss man allerdings beachten, dass jeder Code kaputtgeht, der sich auf blockierende Reads verlässt. Code wie etwa select with exists muss mit expliziten Locks oder auf andere Weise neu geschrieben werden.
  • In einer früheren Firma sahen wir selten Fehler, die auf Inkonsistenzen hindeuteten, etwa Duplicate-Key-Fehler und Foreign-Key-Constraint-Fehler während der Wiederherstellung, nachdem wir den pg_dump-Befehl im Backup-Skript geändert hatten, um parallele Worker zu verwenden (Flag -j).
    Damals wollten wir das bei AWS und auf der PostgreSQL-Mailingliste melden, konnten es aber nicht leicht reproduzieren, kamen deshalb nicht weiter und gaben schließlich auf, indem wir zu Single-Thread-Dumps zurückkehrten. Ich frage mich, ob das Phänomen, das wir damals gesehen haben, mit diesem Problem zusammenhängt.

    • Ich frage mich, ob es eine einzelne Instanz war, eine Instanz mit Standby-Instanz in einer anderen Availability Zone oder der hier getestete Multi-AZ-Cluster.
  • Wenn man diesen Artikel liest, scheint die tatsächliche Auswirkung zu sein, dass bei einem schnellen Read direkt nach einem Write auf dieselbe Zeile veraltete Daten zurückgegeben werden können. Die Write-Transaktion wird als abgeschlossen markiert, aber bevor die verteilte Schicht der Multi-AZ-RDS-Instanz vollständig aktualisiert ist, kann ein sofortiger Read derselben Zeile dazu führen, dass die Zeile noch nicht existiert oder Spalten noch nicht vollständig aktualisiert sind und daher der alte Wert erscheint.
    Aufgrund der Snapshot-Methode von PostgreSQL scheint das nicht zu bedeuten, dass nur einige Bytes eines Multi-Byte-Spaltentyps aktualisiert werden und man dadurch unsinnige Werte liest.
    Am Ende wirkt es wie eine Race Condition, die sich mit der Zeit konvergiert. Oder hat jemand das so gelesen, dass spätere Transaktionen im „long fork“ auch unter normalen Bedingungen möglicherweise nie abgeschlossen werden?

    • Das sind nicht einfach nur veraltete Daten im Sinne eines „konsistenten Snapshots zu einem bestimmten Zeitpunkt, der einige neuere Transaktionen nicht widerspiegelt“. Hier scheint es um eine Situation zu gehen, in der eine Read-only-Transaktion auf einem sekundären Knoten eine Transaktion T beobachtet, aber Transaktionen verpasst, die logisch vor T hätten ausgeführt werden müssen.
  • Die Formulierung „Diese Arbeit wurde ohne Vergütung unabhängig von Jepsen durchgeführt“ ist etwas, das RDBMS-Stakeholder selbst an guten Tagen nicht gern sehen. Intern dürften ein paar E-Mails mit Bedenken herumgegangen sein. Wie immer: Respekt an aphyr.

    • Wen meinst du mit „RDBMS-Stakeholder“?
    • Wenn man auf der Empfängerseite ist, sollte man sich meiner Meinung nach eher freuen. Traditionell kommt niemand unbeschadet durch Jepsen, aber von Aphyr geprüft zu werden bedeutet, dass man ernst genommen wird.
  • Es ist nicht ganz klar, ob das in multi-instance-Upstream-PostgreSQL-Clustern kein Problem ist. Ich frage mich, ob es richtig ist, davon auszugehen, dass AWS in der Cluster-Konfiguration irgendetwas macht oder einen Patch hinzugefügt hat, der dieses Verhalten auslöst.

    • Gute Frage. Ich verstehe die Replikationsarchitektur von AWS noch nicht gut genug, um sie mit Standard-PostgreSQL nachzubauen. Auf einem einzelnen PostgreSQL-Knoten scheint dieses Verhalten nicht aufzutreten, in manchen Replikationskonfigurationen kann es aber passieren.
      PostgreSQL-Replikation gibt es im Allgemeinen in vielen Varianten, und die Ergebnisse unterscheiden sich. Ein Beispiel ist Bin Wangs Patroni-Bericht: https://www.binwang.me/2024-12-02-PostgreSQL-High-Availabili...
    • Bei einem Single-Instance-PostgreSQL-Cluster ist es kein Problem. Betroffen ist aber ein Multi-Instance-PostgreSQL-Cluster mit einem einzelnen Primärknoten und Streaming-/physischer Replikation.
      Was hier ebenfalls festgestellt wurde: PostgreSQL bietet derzeit kein konsistentes Snapshot-Verhalten zwischen Primärknoten und Replikat. Vermutlich lief die Read-only-Transaktion T2 auf einem Sekundärknoten, während die schreibenden Transaktionen T1/T3/T4 auf dem Primärknoten liefen.
      Zum Hintergrund: Der Snapshot eines sekundären PostgreSQL-Knotens stützt sich bei der Entscheidung, welche Transaktionen sichtbar sind, auf die Persistenzreihenfolge der Transaktionen, also auf die Position der Commit-Records im WAL. Auf dem Primärknoten wird die Sichtbarkeitsreihenfolge dagegen dadurch bestimmt, wann das Backend, das die betreffende Transaktion bestätigt hat, erstmals die Benachrichtigung erhält, dass die Transaktion vollständig committet wurde, und wann es danach die Commit-Markierung setzt.
      Innerhalb des Primär- bzw. Sekundärknotens ist die Commit-Reihenfolge zwischen den verbundenen Backends jeweils konsistent, aber zwischen Primär- und Sekundärknoten kann sich die Commit-Reihenfolge etwas unterscheiden. Es wird daran gearbeitet, das zu verbessern, aber das ist noch in einem sehr laufenden Stadium.
    • Es hängt davon ab, was mit „multi instance upstream PostgreSQL cluster“ gemeint ist. PostgreSQL unterstützt Failover der Primärinstanz nicht offiziell, sondern bietet nur PostgreSQL-Replikationsmechanismen, die synchronisiert werden können. Man kann darum herum eigene Tools bauen, um einen Cluster zu konstruieren, und Patroni ist eines dieser Tools.
      AWS scheint PostgreSQL so zu patchen, dass auf zwei Instanzen repliziert wird und es genügt, wenn eine der beiden die Änderung bestätigt. Wann diese Bestätigung erfolgt, ist nicht öffentlich bekannt.
      Persönlich halte ich bei PostgreSQL Replikation auf Dateisystemebene wie drbd für besser. Die ältere Variante der AWS-Multi-AZ-Instanzen dürfte wahrscheinlich so funktioniert haben. Allerdings sinkt dabei der Durchsatz, und man kann nicht von der Sekundärinstanz lesen.
    • Ja, das ist anders. Hier gibt es ein Video, das genauer erklärt, was sie getan haben: https://youtu.be/fLqJXTOhUg4
      Insbesondere diese Stelle: https://youtu.be/fLqJXTOhUg4?t=434
  • Der eingereichte Titel fragt nach dem Kernpunkt: RDS for PostgreSQL 17.4 implementiert Snapshot Isolation nicht korrekt.

    • Weil sich HN-Leute häufig über die Titel von Jepsen-Berichten beschweren, braucht es etwas Kontext. Jepsen-Berichte sind meist das Ergebnis einer langen Zusammenarbeit mit einem Kunden, und Kunden haben oft starke Meinungen zum Berichtstitel.
      Die Diskussionen können ziemlich heftig werden: ob der Titel dem System gegenüber zu hart oder zu freundlich ist, ob er das Bedeutendste unter den rund ein Dutzend gefundenen Problemen enthält, ob er nach Jepsens Anspruch, ein ehrlicher Vermittler bei Ergebnissen zur Datenbanksicherheit zu sein, fair ist, und wie er in zehn Jahren zu verstehen ist, wenn Leute ihn weiterhin verlinken, er aber für neuere Versionen nicht mehr gilt.
      Nach einigen frustrierenden Versuchen umgehe ich dieses Problem inzwischen mit der Regel, alle Berichtstitel nach dem Muster „Jepsen: “ zu benennen. Wenn HN erklärendere oder farbigere Linktexte möchte, kann es sie natürlich selbst auswählen.
    • Auch diesem Kommentar fehlt der Kernpunkt. Es geht um multi-AZ clusters.
      Trotzdem stammt das von Kyle Kingsbury, dem Chuck Norris der Transaktionsgarantien, also sollte AWS antworten oder das klarstellen. Auch dann, wenn es offenbar nur für eine der beiden Optionen von RDS for PostgreSQL gilt, nämlich Multi-AZ-Cluster. Multi-AZ-Deployments können eine oder zwei Standby-DB-Instanzen haben; hier geht es um die Konfiguration mit zwei Standby-DB-Instanzen.
      In der AWS-Dokumentation gibt es kein solches Versprechen. Auch das 5494 Seiten starke RDS-Handbuch erwähnt isolation oder serializable praktisch nur in den Parameterdokumentationen der jeweiligen Engines.
      Auch zur globalen Lesekonsistenz von Multi-AZ-Clustern steht dort nichts. Es heißt zwar, dass bei semi-synchroner Replikation der Writer auf die Bestätigung der Log-Records durch einen Standby wartet, aber zwei Reader können sich auf unterschiedlichen Snapshots befinden.
      [1] - "New Amazon RDS for MySQL & PostgreSQL Multi-AZ Deployment Option: Improved Write Performance & Faster Failover" - https://aws.amazon.com/blogs/aws/amazon-rds-multi-az-db-clus...
      [2] - "Amazon RDS Multi-AZ with two readable standbys: Under the hood" - https://aws.amazon.com/blogs/database/amazon-rds-multi-az-wi...
    • Ich habe den Moderatoren eine E-Mail geschickt und darum gebeten, den Titel in die Formulierung zu ändern, die direkt aus dem verlinkten Artikel kopiert ist: „Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation“
  • Wenn Entwickler Snapshot Isolation voraussetzen, Amazon RDS for PostgreSQL tatsächlich aber nur parallele Snapshot Isolation bietet, frage ich mich, welche Sicherheits- oder Bugs auf Anwendungsebene daraus entstehen können – insbesondere in Multi-AZ-Konfigurationen, die einen Read-Replica-Endpunkt verwenden.

    • Man kann sich einen Ablauf wie git push vorstellen. Man startet eine Transaktion, liest den aktuellen Zustand, prüft, ob er dem erwarteten Zustand entspricht, schreibt den neuen Zustand und committet ihn zusammen mit dem Hash des neuen Zustands. In einem unglücklichen Fall kann dabei ein Commit-Hash entstehen, der zu keinem gültigen Zustand passt.
      Schon die Tatsache, dass sich so etwas schwer nachvollziehen lässt, macht es schwierig, das Problem zu vermeiden. Die einfachste Lösung dürfte daher sein: Wenn ein Schreibvorgang von einem Lesevorgang abhängt, könnte man der Snapshot Isolation vielleicht nahekommen, indem man „nur den Writer-Endpunkt verwendet“.
      Überraschend ist allerdings, dass der Ansatz „nur den Writer-Endpunkt verwenden“ offenbar nicht getestet wurde, insbesondere bei Verfügbarkeitsverlusten.
    • Man kann sich die Situation vorstellen, dass unter einem Beitrag Kommentare hinterlassen werden. Angenommen, der erste kommentierende Nutzer soll ein „first commenter badge“ erhalten.
      User1 schreibt einen Kommentar, User2 schreibt danach ebenfalls einen Kommentar, und anschließend prüft User1 in einer separaten Transaktion, dass es nur einen Kommentar gibt, und erhält das Badge. User2 kann in einer separaten Transaktion dieselbe Prüfung durchführen, nur seinen eigenen Kommentar sehen und ebenfalls das Badge erhalten.
      Bei Snapshot Isolation wäre das unmöglich. Mindestens eine der separaten Transaktionen müsste zwei Kommentare sehen.
      Auch das ursprüngliche Paper zu parallelen Snapshots ist lesenswert: https://scispace.com/pdf/transactional-storage-for-geo-repli...
  • Als ich den Satz „Dieses Verhalten trat in allen getesteten Versionen auf, von 13.15 bis 17.4“ las, war ich besorgt, ob das Upgrade auf die neue Major-Version eine falsche Entscheidung gewesen sei. Das scheint aber nicht der Fall zu sein. Es handelt sich eher um einen Feature Request oder einen alten Bug als um eine Regression.