PostgreSQL Antipatterns: Kampf gegen Horden der "Toten"

Die Funktionen der internen PostgreSQL-Mechanismen ermöglichen es, in einigen Situationen sehr schnell und in anderen nicht so schnell zu sein. Heute werden wir uns mit dem klassischen Beispiel eines Konflikts zwischen der Funktionsweise des DBMS und dem, was der Entwickler damit macht, befassen - den Prinzipien UPDATE vs MVCC .

Kurze Handlung aus einem ausgezeichneten Artikel :
Wenn eine Zeile mit dem Befehl UPDATE geändert wird, werden tatsächlich zwei Operationen ausgeführt: DELETE und INSERT. In der aktuellen Version der Zeile wird xmax gleich der Nummer der Transaktion gesetzt, die UPDATE ausgeführt hat. Dann wird eine neue Version derselben Zeile erstellt. Der xmin-Wert entspricht dem xmax-Wert der vorherigen Version.
Einige Zeit nach Abschluss dieser Transaktion wird die alte oder neue Version, je nachdem, welche COMMIT/ROOLBACKals "tot" (tote Tupel) erkannt, wenn sie VACUUMdurch die Tabelle geht und bereinigt wird.



Dies wird jedoch nicht sofort geschehen, aber Probleme mit den „Toten“ können sehr schnell erkannt werden - mit mehreren oder Massenaktualisierungen von Datensätzen in einer großen Tabelle und wenig später angesichts einer Situation, in der VACUUM nicht helfen kann .

# 1: Ich mag es zu bewegen


Angenommen, Ihre Geschäftslogikmethode funktioniert für sich selbst und erkennt plötzlich, dass das Feld X in einem Datensatz aktualisiert werden muss:

UPDATE tbl SET X = <newX> WHERE pk = $1;

Im weiteren Verlauf wird dann festgestellt, dass auch das Y-Feld aktualisiert werden sollte:

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... und dann auch Z - warum etwas spielen?

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

Wie viele Versionen dieses Datensatzes befinden sich jetzt in der Datenbank? Ja, 4 Stück! Von diesen ist eine relevant, und 3 müssen [auto] VACUUM für Sie abholen.

Nicht so! Verwenden Sie die Aktualisierung aller Felder in einer Anfrage - fast immer kann die Logik der Methode folgendermaßen geändert werden:

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

# 2: Verwenden Sie IS UNTERSCHIEDLICH, Luke!


Sie wollten also immer noch viele, viele Datensätze in der Tabelle aktualisieren (z. B. während der Verwendung eines Skripts oder Konverters). Und so etwas fliegt ins Drehbuch:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

In ungefähr dieser Form tritt häufig und fast immer eine Abfrage auf, um kein leeres neues Feld auszufüllen, sondern um einige Fehler in den Daten zu korrigieren. Darüber hinaus wird die Richtigkeit bereits vorhandener Daten überhaupt nicht berücksichtigt - aber vergebens! Das heißt, die Aufzeichnung wird neu geschrieben, auch wenn es genau das war, was ich wollte - warum? Richtig:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

Viele Menschen sind sich der Existenz eines so wunderbaren Operators nicht bewusst. Hier ist ein Spickzettel für IS DISTINCT FROMandere logische Operatoren:

... und ein wenig über Operationen an komplexen ROW()Ausdrücken:

# 3: Ich erkenne meine Liebe daran, dass ich ... blockiere


Führen Sie zwei identische parallele Prozesse aus , von denen jeder auf die Aufzeichnungsmarke gerichtet ist, die "in Betrieb" ist:

UPDATE tbl SET processing = TRUE WHERE pk = $1;

Selbst wenn diese Prozesse im Wesentlichen voneinander unabhängig sind, jedoch im Rahmen einer ID, „sperrt“ der zweite Client bei dieser Anforderung, bis die erste Transaktion abgeschlossen ist.

Lösung 1 : Die Aufgabe wird auf die vorherige reduziert.

Fügen Sie einfach noch einmal hinzu IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

In diesem Formular ändert die zweite Anforderung einfach nichts in der Datenbank, da bereits "alles so ist, wie es sollte" - daher erfolgt keine Blockierung. Ferner wird die Tatsache der "Nichtexistenz" des Datensatzes bereits in dem angewendeten Algorithmus verarbeitet.

Entscheidung Nr. 2 : Beratungssperren

Ein großes Thema für einen separaten Artikel, in dem Sie Informationen zu den Anwendungsmethoden und dem "Rechen" von Empfehlungssperren lesen können .

Lösung 3 : ohne [d] Smart Calls

Aber genau, genau, sollten Sie gleichzeitig mit demselben Datensatz arbeiten ? Oder haben Sie zum Beispiel immer noch mit clientseitigen Geschäftslogik-Aufrufalgorithmen herumgespielt? Und wenn Sie darüber nachdenken? ..

All Articles