Entsperren des Postgres Lock Managers. Bruce Momjian

Die Entschlüsselung des Berichts von Bruce Momjian aus dem Jahr 2020 "Den Postgres Lock Manager entsperren".

Entsperren des Postgres Lock Managers. Bruce Momjian

(Hinweis: Alle SQL-Abfragen aus den Folien können Sie unter diesem Link abrufen: http://momjian.us/main/writings/pgsql/locking.sql)

Hallo! Es ist großartig, wieder hier in Russland zu sein. Ich entschuldige mich, dass ich letztes Jahr nicht kommen konnte, aber Ivan und ich haben in diesem Jahr große Pläne. Ich hoffe, ich werde viel öfter hier sein. Ich liebe es, nach Russland zu reisen. Ich werde Tyumen und Twer besuchen. Ich freue mich sehr darauf, diese Städte zu erleben.

Mein Name ist Bruce Momjian. Ich arbeite bei EnterpriseDB und beschäftige mich seit über 23 Jahren mit Postgres. Ich lebe in Philadelphia, USA. Ich reise etwa 90 Tage im Jahr und besuche rund 40 Konferenzen. Meine Webseite, die die Folien enthält, die ich Ihnen jetzt zeigen werde. Nach der Konferenz können Sie sie von meiner persönlichen Website herunterladen. Dort finden Sie auch etwa 30 Präsentationen, Videos und eine große Anzahl von Blogeinträgen, mehr als 500. Es ist eine recht umfassende Ressource. Wenn Sie an diesem Material interessiert sind, lade ich Sie ein, es zu nutzen.

Früher war ich Lehrer und Professor, bevor ich mit Postgres gearbeitet habe. Ich freue mich sehr, Ihnen jetzt das zu erzählen, was ich Ihnen mitteilen möchte. Es ist eine meiner interessantesten Präsentationen. Diese Präsentation enthält 110 Folien. Wir beginnen mit einfachen Themen, und am Ende wird die Präsentation immer komplexer und anspruchsvoller.

Entsperren des Postgres Lock Managers. Bruce Momjian

Das ist ein recht unangenehmes Thema. Sperrung ist nicht das populärste Thema. Wir möchten, dass es irgendwo verschwindet. Es ist wie der Besuch beim Zahnarzt.

Entsperren des Postgres Lock Managers. Bruce Momjian

  1. Die Sperrung ist ein Problem für viele Menschen, die mit Datenbanken arbeiten und mehrere Prozesse gleichzeitig haben. Sie benötigen eine Sperrung. Das heißt, heute werde ich Ihnen grundlegende Kenntnisse über Sperrungen vermitteln.
  2. Transaktionsidentifikatoren. Das ist der eher langweilige Teil der Präsentation, aber sie müssen verstanden werden.
  3. Als Nächstes sprechen wir über die Arten von Sperrungen. Das ist ein eher mechanischer Teil.
  4. Und dann geben wir einige Beispiele für Sperrungen. Und das wird für das Verständnis recht kompliziert sein.

Entsperren des Postgres Lock Managers. Bruce Momjian

Lassen Sie uns über Sperrungen sprechen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Unsere Terminologie ist recht komplex. Wie viele von Ihnen wissen, wo dieser Ausschnitt herkommt? Zwei Personen. Es stammt aus einem Spiel namens "Kolossales Abenteuer in der Höhle". Das war ein Text-Computer-Spiel in den 80er Jahren, wenn ich mich recht erinnere. Man musste in eine Höhle, ein Labyrinth, eintreten und der Text änderte sich, aber der Inhalt war jedes Mal ungefähr gleich. So erinnere ich mich an dieses Spiel.

Entsperren des Postgres Lock Managers. Bruce Momjian

Hier sehen wir die Namen der Sperren, die von Oracle zu uns gekommen sind. Wir verwenden sie.

Entsperren des Postgres Lock Managers. Bruce Momjian

Hier sind Begriffe, die mich verwirren. Zum Beispiel SHARE UPDATE EXCLUSIVE. Dann SHARE RAW EXCLUSIVE. Ehrlich gesagt sind diese Bezeichnungen nicht sehr verständlich. Wir werden versuchen, sie genauer zu betrachten. Einige enthalten das Wort „share“, was so viel wie – sich abspalten bedeutet. Einige enthalten das Wort „exclusive“ – exklusiv. Einige enthalten beide Wörter. Ich möchte beginnen mit der Funktionsweise dieser Sperren.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und auch sehr wichtig ist das Wort „Zugang“ – access. Und das Wort „row“ – Zeile. Das heißt, Zugriffverteilung, Zeilenverteilung.

Entsperren des Postgres Lock Managers. Bruce Momjian

Ein weiteres Thema, das man in Postgres verstehen muss und über das ich leider in meinem Vortrag nicht sprechen kann, ist MVCC. Ich habe dazu eine separate Präsentation auf meiner Website. Und wenn Sie denken, dass diese Präsentation kompliziert ist, dann ist MVCC wahrscheinlich meine schwierigste. Wenn es Sie interessiert, können Sie sie auf der Webseite ansehen. Sie können das Video anschauen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Ein weiterer Punkt, den wir verstehen müssen, sind die Transaktions-IDs. Viele Transaktionen können ohne eindeutige Identifikatoren nicht funktionieren. Hier erklären wir, was eine Transaktion ist. In Postgres gibt es zwei Transaktionsnummerierungssysteme. Ich weiß, dass das keine besonders elegante Lösung ist.

Entsperren des Postgres Lock Managers. Bruce Momjian

Bitte beachten Sie, dass die Folien recht komplex sein werden, daher sollten Sie besonders auf das achten, was rot gekennzeichnet ist — darauf müssen Sie Ihr Augenmerk richten.

Entsperren des Postgres Lock Managers. Bruce Momjian

http://momjian.us/main/writings/pgsql/locking.sql

Schauen wir uns das an. Die Transaktionsnummer ist rot hervorgehoben. Hier wird die Funktion SELECT pg_back angezeigt. Sie gibt meine Transaktion und die ID dieser Transaktion zurück.

Ein weiterer Punkt: Wenn Ihnen diese Präsentation gefällt und Sie sie in Ihrer Datenbank ausführen möchten, können Sie auf den mit Rosa hervorgehobenen Link klicken und das SQL für diese Präsentation herunterladen. Sie können es einfach in Ihrem PSQL ausführen, und die gesamte Präsentation wird sofort auf Ihrem Bildschirm angezeigt. Sie enthält keine Farben, aber zumindest können wir sie sehen.

Entsperren des Postgres Lock Managers. Bruce Momjian

In diesem Fall sehen wir die Transaktions-ID. Dies ist die Nummer, die wir ihr zugewiesen haben. Es gibt auch einen anderen Typ der Transaktions-ID in Postgres, der als virtuelle Transaktions-ID bezeichnet wird.

Und wir müssen das verstehen. Das ist sehr wichtig, sonst können wir die Sperrung in Postgres nicht nachvollziehen.

Eine virtuelle Transaktions-ID ist eine Transaktions-ID, die keine festen Werte enthält. Wenn ich beispielsweise einen SELECT-Befehl ausführe, werde ich wahrscheinlich die Datenbank nicht ändern und nichts blockieren. Daher geben wir dieser Transaktion bei einem einfachen SELECT keine feste ID. Wir geben ihr nur eine virtuelle ID.

Das erhöht die Leistung von Postgres und verbessert die Möglichkeiten zur Bereinigung, daher besteht die virtuelle Transaktions-ID aus zwei Zahlen. Die erste Zahl vor dem Schrägstrich ist die Backend-ID. Rechts sehen wir einfach einen Zähler.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn ich also eine Abfrage starte, sagt er, dass die Backend-ID – 2 ist.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und wenn ich eine Reihe solcher Transaktionen starte, sehen wir, dass der Zähler jedes Mal erhöht wird, wenn ich eine Abfrage starte. Zum Beispiel, wenn ich die Abfragen 2/10, 2/11, 2/12 usw. starte.

Entsperren des Postgres Lock Managers. Bruce Momjian

Bitte beachten Sie, dass es hier zwei Spalten gibt. Links sehen wir die virtuelle Transaktions-ID – 2/12. Rechts haben wir die permanente Transaktions-ID. Und dieses Feld ist leer. Diese Transaktion verändert also die Datenbank nicht. Daher weise ich ihr keine permanente Transaktions-ID zu.

Entsperren des Postgres Lock Managers. Bruce Momjian

Sobald ich den Befehl ANALYZE ausführe, gibt mir dieselbe Abfrage die permanente Transaktions-ID. Sehen Sie, wie sich das geändert hat. Früher hatte ich diese ID nicht, jetzt ist sie da.

Entsperren des Postgres Lock Managers. Bruce Momjian

Hier ist also eine weitere Abfrage, eine weitere Transaktion. Die virtuelle Transaktionsnummer ist – 2/13. Und wenn ich um die permanente Transaktions-ID bitte, erhalte ich sie, wenn ich die Abfrage starte.

Entsperren des Postgres Lock Managers. Bruce Momjian

Also, noch einmal: Wir haben eine virtuelle Transaktions-ID und eine permanente Transaktions-ID. Verstehen Sie diesen Punkt, um das Verhalten von Postgres zu begreifen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wir kommen zum dritten Abschnitt. Hier werden wir einfach die verschiedenen Arten von Sperren in Postgres durchgehen. Das ist nicht besonders spannend. Der letzte Abschnitt wird viel interessanter sein. Aber wir müssen die Grundlagen behandeln, denn sonst werden wir nicht verstehen, was als Nächstes kommt.

Wir werden diesen Abschnitt durchgehen und uns jeden Typ von Sperren ansehen. Ich werde Ihnen Beispiele zeigen, wie sie gesetzt werden, wie sie funktionieren, und ich zeige Ihnen einige Abfragen, die Sie verwenden können, um zu sehen, wie die Sperren in Postgres arbeiten.

Entsperren des Postgres Lock Managers. Bruce Momjian

Um eine Abfrage zu erstellen und zu sehen, was in Postgres passiert, müssen wir eine Abfrage in der Systemansicht ausführen. In diesem Fall ist pg_lock in Rot hervorgehoben. Pg_lock ist eine Systemtabelle, die uns sagt, welche Sperren derzeit in Postgres verwendet werden.

Dennoch fällt es mir sehr schwer, Ihnen pg_lock allein zu zeigen, da es ziemlich kompliziert ist. Daher habe ich eine Ansicht erstellt, die pg_locks anzeigt. Und sie erledigt auch für mich einige Aufgaben, die mir helfen, es besser zu verstehen. Das heißt, sie schließt meine Sperren, meine eigene Sitzung usw. aus. Es ist einfach Standard-SQL und hilft mir, besser zu zeigen, was passiert.

Entsperren des Postgres Lock Managers. Bruce Momjian

Ein weiteres Problem ist, dass diese Ansicht sehr umfangreich ist, weshalb ich eine zweite – lockview2 – erstellen musste.

Entsperren des Postgres Lock Managers. Bruce Momjian Und sie zeigt mir zusätzliche Spalten aus der Tabelle. Und noch eine weitere, die mir die restlichen Spalten zeigt. Es ist ziemlich kompliziert, deshalb habe ich versucht, es so einfach wie möglich darzustellen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Also haben wir eine Tabelle erstellt, die Lockdemo heißt. Und wir haben dort eine Zeile angelegt. Das ist unsere Beispiel-Tabelle. Und wir werden Abschnitte erstellen, um Ihnen einfach Beispiele für Sperren zu zeigen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Also eine Zeile, eine Spalte. Der erste Sperrtyp heißt ACCESS SHARE. Das ist die am wenigsten einschränkende Sperre. Das bedeutet, dass sie praktisch nicht mit anderen Sperren in Konflikt steht.

Wenn wir die Sperrung explizit definieren wollen, führen wir den Befehl „lock table“ aus. Dies wird die Tabelle eindeutig sperren, d.h. im ACCESS SHARE-Modus führen wir lock table aus. Und wenn ich PSQL im Hintergrund starte, starte ich somit eine zweite Sitzung aus meiner ersten Sitzung. Was mache ich hier? Ich wechsle zu einer anderen Sitzung und sage ihr: „Zeig mir die lockview für diese Anfrage“. Und hier habe ich AccessShareLock in dieser Tabelle. Genau das habe ich angefordert. Und es zeigt, dass die Sperre zugewiesen wurde. Ganz einfach.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn wir uns die zweite Spalte ansehen, ist dort nichts. Sie sind leer.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn ich den Befehl „SELECT“ ausführe, ist das eine implizite (einfache) Möglichkeit, ein AccessShareLock anzufordern. Also gebe ich meine Tabelle frei und führe die Anfrage aus, die mehrere Zeilen zurückgibt. Und in einer der Zeilen sehen wir AccessShareLock. Somit ruft SELECT AccessShareLock in der Tabelle auf. Und es konfliktiert praktisch mit nichts, da dies eine Lock auf niedriger Ebene ist.

Entsperren des Postgres Lock Managers. Bruce Momjian

Was passiert, wenn ich SELECT ausführe und drei verschiedene Tabellen habe? Früher habe ich nur eine Tabelle ausgeführt, jetzt führe ich drei aus: pg_class, pg_namespace und pg_attribute.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und jetzt, wenn ich die Anfrage anschaue, sehe ich 9 AccessShareLocks in drei Tabellen. Warum? Die drei Tabellen sind in Blau hervorgehoben: pg_attribute, pg_class, pg_namespace. Aber Sie können auch sehen, dass alle Indizes, die über diese Tabellen definiert sind, ebenfalls einen AccessShareLock haben.

Und dies ist eine Sperre, die praktisch nicht mit anderen in Konflikt steht. Alles, was sie tut, ist, dass sie uns einfach daran hindert, die Tabelle zurückzusetzen, während wir sie abfragen. Das macht Sinn. D. h. wenn wir die Tabelle abfragen und sie in diesem Moment verschwindet, ist das nicht korrekt, also AccessShare ist eine niedrigstufige Sperre, die uns sagt: "Löschen Sie diese Tabelle nicht, während ich arbeite".. Im Wesentlichen ist das alles, was sie tut.

Entsperren des Postgres Lock Managers. Bruce Momjian

ROW SHARE ist eine Sperre, die sich etwas unterscheidet.

Entsperren des Postgres Lock Managers. Bruce Momjian

Lassen Sie uns ein Beispiel nehmen. SELECT ROW SHARE ist eine Methode zur Sperrung jeder Zeile einzeln. So kann niemand sie löschen oder ändern, während wir sie betrachten.

Entsperren des Postgres Lock Managers. Bruce MomjianWas macht also SHARE LOCK? Wir sehen, dass die Transaktions-ID 681 für die SELECT-Abfrage verantwortlich ist. Und das ist interessant. Was ist hier passiert? Zum ersten Mal sehen wir eine Nummer im Feld „Lock“. Wir nehmen die Transaktions-ID, und sie sagt uns, dass sie exklusiv gesperrt wird. Alles, was sie tut, ist zu sagen, dass ich eine Zeile habe, die technisch irgendwo in der Tabelle gesperrt ist. Aber es sagt nicht, wo genau. Ein wenig später werden wir das genauer ansehen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Hier sagen wir, dass die Sperre von uns verwendet wird.

Entsperren des Postgres Lock Managers. Bruce Momjian

Die exklusive Sperre besagt ausdrücklich, dass sie exklusiv ist. Und auch wenn Sie eine Zeile in dieser Tabelle löschen, passiert genau das, wie Sie sehen können.

Entsperren des Postgres Lock Managers. Bruce Momjian

SHARE EXCLUSIVE ist eine längere Sperre.

Entsperren des Postgres Lock Managers. Bruce Momjian

Das ist der (ANALYZE) Befehl des Analysators, der verwendet wird.

Entsperren des Postgres Lock Managers. Bruce Momjian

SHARE LOCK – Sie können ausdrücklich im Freigabemodus sperren.

Entsperren des Postgres Lock Managers. Bruce Momjian

Sie können auch einen eindeutigen Index erstellen. Und dort können Sie SHARE LOCK sehen, das Teil davon ist. Es sperrt die Tabelle und setzt eine SHARE LOCK auf.

Standardmäßig bedeutet SHARE LOCK auf einer Tabelle, dass andere Personen die Tabelle lesen können, aber niemand sie modifizieren kann. Und genau das passiert, wenn Sie einen eindeutigen Index erstellen.

Wenn ich einen eindeutigen Index concurrently erstelle, habe ich eine andere Art der Sperrung, denn wie Sie sich erinnern, verringert die Verwendung von concurrently Indizes die Anforderungen an die Sperrung. Und wenn ich eine normale Sperrung mit einem normalen Index verwende, werde ich damit das Schreiben in den Index der Tabelle während seiner Erstellung verhindern. Wenn ich einen concurrently Index verwende, muss ich einen anderen Sperrtyp verwenden.

Entsperren des Postgres Lock Managers. Bruce Momjian

SHARE ROW EXCLUSIVE – auch hier kann sie explizit (eindeutig) festgelegt werden.

Entsperren des Postgres Lock Managers. Bruce Momjian

Oder wir können eine Regel erstellen, d.h. einen bestimmten Fall festlegen, in dem sie verwendet wird.

Entsperren des Postgres Lock Managers. Bruce Momjian

EXCLUSIVE-Sperre bedeutet, dass niemand sonst die Tabelle ändern kann.

Entsperren des Postgres Lock Managers. Bruce Momjian

Hier sehen wir verschiedene Arten von Sperren.

Entsperren des Postgres Lock Managers. Bruce Momjian

ACCESS EXCLUSIVE, zum Beispiel, ist ein Sperrbefehl. Wenn Sie zum Beispiel CLUSTER table, bedeutet das, dass niemand dort schreiben kann. Und es sperrt nicht nur die Tabelle selbst, sondern auch die Indizes.

Entsperren des Postgres Lock Managers. Bruce Momjian

Dies ist die zweite Seite der ACCESS EXCLUSIVE-Sperre, auf der wir genau sehen, was sie in der Tabelle sperrt. Sie sperrt einzelne Zeilen der Tabelle, was ziemlich interessant ist.

Das ist die gesamte grundlegende Information, die ich geben wollte. Wir haben über Sperren gesprochen, über Transaktions-IDs, über virtuelle Transaktions-IDs und über permanente Transaktions-IDs.

Entsperren des Postgres Lock Managers. Bruce Momjian

Jetzt werden wir zu den Beispielen von Sperren übergehen. Das ist der interessanteste Teil. Wir werden uns sehr interessante Fälle ansehen. Mein Ziel in dieser Präsentation ist es, Ihnen ein besseres Verständnis dafür zu geben, was Postgres tatsächlich tut, wenn es versucht, bestimmte Dinge zu sperren. Ich denke, es kann sehr gut einzelne Teile sperren.

Lassen Sie uns bestimmte Beispiele betrachten.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wir beginnen mit Tabellen und einer Zeile in der Tabelle. Wenn ich etwas einfüge, wird mir der ExclusiveLock angezeigt, die Transaktions-ID und der ExclusiveLock auf der Tabelle.

Entsperren des Postgres Lock Managers. Bruce Momjian

Was passiert, wenn ich noch zwei Zeilen einfüge? Jetzt haben wir drei Zeilen in unserer Tabelle. Ich habe eine Zeile hinzugefügt und das ist das Ergebnis. Und wenn ich noch zwei Zeilen einfüge, was ist hier seltsam? Es gibt eine Eigenart, denn ich habe drei Zeilen zu dieser Tabelle hinzugefügt, aber ich habe immer noch zwei Zeilen in der Sperrtabelle. Das ist im Grunde genommen das grundlegende Verhalten von Postgres.

Viele denken, dass wenn Sie in der Datenbank 100 Zeilen sperren, Sie 100 Sperrdatensätze erstellen müssen. Wenn ich gleichzeitig 1.000 Zeilen sperre, benötige ich 1.000 solcher Anfragen. Und wenn ich eine Million oder eine Milliarde sperren muss? Aber wenn wir es so machen, wird es nicht gut funktionieren. Wenn Sie ein System verwendet haben, das Sperrdatensätze für jede einzelne Zeile erstellt, merken Sie, dass das kompliziert ist. Denn Sie müssen die Sperrtabelle sofort definieren, die überlaufen kann, aber Postgres macht das nicht.

Auf dieser Folie ist es sehr wichtig, dass hier eindeutig dargestellt wird, dass es ein weiteres System gibt, das innerhalb von MVCC arbeitet und einzelne Zeilen sperrt. Daher erstellt Postgres, wenn Sie Milliarden von Zeilen sperren, nicht eine Milliarde separater Sperrbefehle. Das hat sich sehr positiv auf die Leistung ausgewirkt.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wie sieht es mit dem Update aus? Ich aktualisiere gerade eine Zeile und Sie können sehen, dass es sofort zwei verschiedene Operationen durchgeführt hat. Es hat gleichzeitig die Tabelle gesperrt, aber auch den Index. Und es musste den Index sperren, weil es auf dieser Tabelle einzigartige Einschränkungen gibt. Wir möchten sicherstellen, dass niemand ihn verändert, also sperren wir ihn.

Entsperren des Postgres Lock Managers. Bruce Momjian

Was passiert, wenn ich zwei Zeilen aktualisieren möchte? Und wir sehen, dass es sich ähnlich verhält. Wir führen doppelt so viele Updates durch, aber die Anzahl der gesperrten Zeilen bleibt genau gleich.

Wenn Sie sich fragen, wie Postgres das macht, müssen Sie meine Vorträge über MVCC hören, um zu erfahren, wie Postgres intern diese Zeilen markiert, die es ändert. Postgres hat einen Weg, wie es das macht, aber es tut dies nicht auf der Ebene von Tabellenverriegelungen, sondern auf einer niedrigeren und effizienteren Ebene.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und was ist, wenn ich etwas löschen möchte? Wenn ich beispielsweise eine Zeile lösche und meine zwei Einsätze mit der Sperrung immer noch vorhanden sind, selbst wenn ich alle löschen möchte, sind sie immer noch vorhanden.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und sagen wir, ich möchte 1.000 Zeilen einfügen und danach entweder 1.000 Zeilen löschen oder hinzufügen. Die einzelnen Zeilen, die ich hinzufüge oder ändere, werden hier nicht aufgezeichnet. Sie werden auf einer niedrigeren Ebene innerhalb der Zeile selbst aufgezeichnet. Und während meines Vortrags über MVCC habe ich dies im Detail erklärt. Es ist jedoch sehr wichtig, dass Sie beim Analysieren von Sperren sicherstellen, dass Sie eine Sperre auf Tabellenebene haben und hier nicht sehen, wie die einzelnen Zeilen aufgezeichnet werden.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und wie sieht es mit expliziten Sperren aus?

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn ich auf „Aktualisieren“ klicke, habe ich zwei gesperrte Zeilen. Und wenn ich sie alle auswähle und auf „Überall aktualisieren“ klicke, bleiben mir trotzdem zwei Sperrposten.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wir erstellen keine separaten Einträge für jede einzelne Zeile. Denn dann leidet die Leistung, da könnte es zu viel davon geben. Und wir könnten in einer unangenehmen Situation enden.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und das Gleiche gilt, wenn wir Shared verwenden, wir können es für alle 30 machen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wir stellen unsere Tabelle wieder her, löschen alles und fügen dann eine Zeile erneut ein.

Entsperren des Postgres Lock Managers. Bruce Momjian

Eine weitere Verhaltensweise, die Sie in Postgres sehen, ist ein sehr bekanntes und gewünschtes Verhalten – dass Sie Update oder Select durchführen können. Und Sie können dies gleichzeitig tun. Und Select blockiert nicht das Update, und umgekehrt. Wir sagen dem Lesenden, dass er den Schreibenden nicht blockiert, und der Schreibende blockiert den Lesenden nicht.

Ich zeige Ihnen ein Beispiel dafür. Ich werde jetzt eine Auswahl treffen. Dann werden wir ein INSERT durchführen. Und Sie werden dann sehen können – 694. Sie werden die ID der Transaktion sehen, die diesen Insert durchgeführt hat. Und so funktioniert das.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und wenn ich jetzt auf meine Backend-ID schaue, dann ist sie – 695.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und ich kann sehen, dass 695 in meiner Tabelle erscheint.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und wenn ich hier ein Update so durchführe, erhalte ich einen anderen Fall. In diesem Fall ist 695 eine exklusive Sperre, und das Update hat ein ähnliches Verhalten, aber zwischen ihnen entsteht kein Konflikt, was ziemlich ungewöhnlich ist.

Und Sie können feststellen, dass oben – dies ist ein ShareLock, und unten – dies ist ein ExclusiveLock. Und beide Transaktionen haben stattgefunden.

Und man muss sich meinen Vortrag über MVCC anhören, um zu verstehen, wie das funktioniert. Aber dies ist eine Illustration dafür, dass man dies gleichzeitig machen kann, also SELECT und UPDATE gleichzeitig durchführen kann.

Entsperren des Postgres Lock Managers. Bruce Momjian

Lass uns zurücksetzen und noch einmal eine Operation durchführen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn Sie versuchen, gleichzeitig zwei Updates auf derselben Zeile auszuführen, wird es gesperrt. Und denken Sie daran, dass ich gesagt habe, dass ein Leser einen Schreiber nicht sperrt, aber ein Schreiber einen Leser sperrt, aber ein Schreiber blockiert einen anderen Schreiber. Das bedeutet, dass wir nicht zwei Personen gleichzeitig dasselbe Update auf derselben Zeile durchführen können. Einer muss warten, bis der andere fertig ist.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und um dies zu veranschaulichen, schaue ich mir die Lockdemo-Tabelle an. Und wir werden eine Zeile betrachten. Bei der Transaktion 698.

Wir haben es auf 2 aktualisiert. 699 ist das erste Update. Und es war erfolgreich oder es befindet sich in einer ausstehenden Transaktion und wartet darauf, dass wir bestätigen oder stornieren.

Entsperren des Postgres Lock Managers. Bruce Momjian

Aber schauen Sie sich das andere an – 2/51 – das ist unsere erste Transaktion, unsere erste Sitzung. 3/112 – das ist die zweite Anfrage, die oben erschien und diesen Wert auf 3 änderte. Und wenn Sie bemerken, hat sich die obere Anfrage selbst blockiert, die 699 ist. Aber 3/112 hat keine Sperre bereitgestellt. In der Spalte Lock_mode steht, dass es wartet. Es wartet auf 699. Und wenn Sie sehen, wo 699 ist, ist es höher. Und was hat die erste Sitzung gemacht? Sie hat eine exklusive Sperre auf ihrer eigenen Transaktions-ID erstellt. So funktioniert Postgres. Es sperrt die eigene Transaktions-ID. Und wenn Sie warten möchten, bis jemand bestätigt oder stornert, müssen Sie warten, bis eine ausstehende Transaktion vorhanden ist. Und deshalb können wir eine merkwürdige Zeile sehen.

Schauen wir uns das noch einmal an. Auf der linken Seite sehen wir unsere Verarbeitungs-ID. In der zweiten Spalte sehen wir unsere virtuelle Transaktions-ID, und in der dritten sehen wir den lock_type. Was bedeutet das? Im Grunde genommen besagt sie, dass sie die Transaktions-ID blockiert. Aber beachten Sie, dass in allen Zeilen unten 'relation' steht. Deshalb haben Sie zwei Arten von Sperren in der Tabelle. Es gibt die Sperre 'relation'. Und es gibt auch die Sperre 'transactionid', bei der Sie selbst blockieren, genau das passiert in der ersten Zeile oder ganz unten, wo transationid steht, wo wir erwarten, dass 699 seine Operation abschließt.

Ich sehe, was hier passiert. Gleichzeitig geschehen hier zwei Dinge. Sie betrachten die Sperre nach Transaktions-ID in der ersten Zeile, die sich selbst sperrt. Und sie sperrt sich selbst, um die Leute warten zu lassen.

Wenn Sie sich die 6. Zeile ansehen, ist das dieselbe Aufzeichnung wie die erste. Daher wird die Transaktion 699 blockiert. 700 sperrt sich ebenfalls selbst. Und dann sehen Sie in der unteren Reihe, dass wir warten, bis 699 seine Operation abschließt.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und in lock_type, tuple sehen Sie Zahlen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Sie können sehen, dass es 0/10 ist. Und das ist die Seitennummer sowie der Offset dieser bestimmten Zeile.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und Sie sehen, dass es 0/11 wird, wenn wir aktualisieren.

Entsperren des Postgres Lock Managers. Bruce Momjian

Aber in Wirklichkeit sind es 0/10, weil ich auf diesen Vorgang warte. Wir haben die Möglichkeit zu sehen, dass dies die Zeile ist, auf die ich warte, um zu bestätigen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Sobald wir es bestätigt und auf Commit gedrückt haben und wenn das Update abgeschlossen ist, ist das, was wir wieder erhalten. Transaktion 700 ist die einzige Sperre, sie wartet auf niemanden mehr, weil sie bereits committet wurde. Sie wartet lediglich darauf, dass die Transaktion abgeschlossen wird. Sobald 699 endet, warten wir auf nichts mehr. Und jetzt sagt Transaktion 700, dass alles in Ordnung ist, dass sie alle benötigten Sperren in den genehmigten Tabellen hat.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und um das Ganze noch komplizierter zu machen, erstellen wir eine weitere Ansicht, die uns diesmal eine Hierarchie bereitstellt. Ich erwarte nicht, dass Sie diese Anfrage verstehen. Aber sie wird uns eine klarere Sicht darauf geben, was passiert.

Entsperren des Postgres Lock Managers. Bruce Momjian

Dies ist eine rekursive Ansicht, die auch noch einen weiteren Abschnitt hat. Und sie gibt dann alles zusammen zurück. Lassen Sie uns das verwenden.

Entsperren des Postgres Lock Managers. Bruce Momjian

Was ist, wenn wir drei gleichzeitige Aktualisierungen durchführen und sagen, dass die Zeile jetzt drei beträgt. Und wir ändern 3 in 4.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und hier sehen wir 4. Und die Transaktions-ID 702.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und dann werde ich 4 in 5 ändern. 5 in 6, 6 in 7. Und ich stelle eine Reihe von Personen auf, die darauf warten, dass diese eine Transaktion abgeschlossen wird.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und alles wird klar. Welche ist die erste Reihe? Das ist 702. Das ist die Transaktions-ID, die ursprünglich diesen Wert gesetzt hat. Und was steht in der Spalte Granted? Ich habe Markierungen f. Das sind meine Updates, die (5, 6, 7) nicht genehmigt werden können, weil wir darauf warten, dass die Transaktions-ID 702 abgeschlossen wird. Da gibt es eine Sperre der Transaktions-ID. Und es ergibt 5 transaktionsspezifische Sperren.

Und wenn Sie sich 704 und 705 ansehen, steht dort noch nichts, weil sie noch nicht wissen, was passiert. Sie schreiben einfach, dass sie keine Ahnung haben, was los ist. Und sie werden einfach in den Schlaf gehen, weil sie darauf warten, dass jemand fertig ist und sie wecken, wenn die Möglichkeit besteht, die Reihe zu wechseln.

Entsperren des Postgres Lock Managers. Bruce Momjian

So sieht das aus. Es ist klar, dass sie alle auf die 12. Zeile warten.

Entsperren des Postgres Lock Managers. Bruce Momjian

Das ist, was wir hier gesehen haben. Hier ist 0/12.

Entsperren des Postgres Lock Managers. Bruce Momjian

Sobald die erste Transaktion genehmigt ist, können Sie hier sehen, wie die Hierarchie funktioniert. Jetzt wird alles klar. Sie werden alle bereinigt. Und sie befinden sich tatsächlich noch in der Warteschleife.

Entsperren des Postgres Lock Managers. Bruce Momjian

So läuft es ab. 702 wird committet. Jetzt erhält 703 die Zeilensperre, und dann wartet 704, bis 703 committet wurde. Auch 705 wartet darauf. Und wenn all dies abgeschlossen ist, bereinigen sie sich selbst. Ich möchte darauf hinweisen, dass sich alle hintereinander anstellen. Es erinnert sehr an eine Situation im Verkehr, wenn alle auf das erste Auto warten. Das erste Auto hält an, und alle stellen sich in einer langen Reihe auf. Dann fährt es weiter, dann kann das nächste Auto vorfahren, seine Sperre erhalten usw.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und falls Ihnen das nicht kompliziert genug erschien, sprechen wir jetzt über Deadlocks. Ich weiß nicht, wer von Ihnen schon einmal damit zu tun hatte. Das ist ein häufiges Problem in Datenbanksystemen. Ein Deadlock tritt dann auf, wenn eine Sitzung darauf wartet, dass eine andere Sitzung etwas ausführt. Währenddessen wartet die andere Sitzung darauf, dass die erste Sitzung etwas ausführt.

Und wenn beispielsweise Ivan sagt: „Gib mir irgendetwas“, und ich sage: „Nein, ich gebe es dir nur, wenn du mir etwas anderes gibst“. Und er sagt: „Nein, ich gebe dir das nicht, wenn du mir nicht etwas gibst“. Und dann stecken wir in einer Situation der toten Blockade fest. Ich bin mir sicher, dass Ivan das nicht tun würde, aber Sie verstehen den Sinn, dass zwei Personen etwas erhalten wollen und sie nicht bereit sind, es zu geben, bis die andere Person ihnen das gibt, was sie wollen. Und hier gibt es keine Lösung.

Und im Grunde muss Ihre Datenbank das erkennen. Und dann muss eine der Sitzungen beendet oder geschlossen werden, denn sonst bleiben sie dort für immer. Und wir sehen das in Datenbanken, wir sehen das in Betriebssystemen. Und an allen Stellen, wo wir parallele Prozesse haben, kann so etwas passieren.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und wir werden jetzt zwei Deadlocks einrichten. Wir setzen 50 und 80. In der ersten Reihe werde ich ein Update von 50 auf 50 durchführen. Ich erhalte die Transaktionsnummer 710.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und dann werde ich 80 auf 81 und 50 auf 51 ändern.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und so wird es aussehen. Und deshalb hat 710 eine Blockierung der Reihe, während 711 auf eine Bestätigung wartet. Wir haben das gesehen, als wir aktualisiert haben. 710 ist der Besitzer unserer Reihe. Und 711 wartet darauf, dass 710 die Transaktion abschließt.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und dort steht sogar, in welcher Zeile es zu Deadlocks kommt. Und hier wird es seltsam.

Entsperren des Postgres Lock Managers. Bruce Momjian

Jetzt aktualisieren wir 80 auf 80.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und hier beginnen die Deadlocks. 710 wartet auf eine Antwort von 711, während 711 auf 710 wartet. Das wird nicht gut enden. Und es gibt keinen Ausweg. Sie werden auf eine Antwort des jeweils anderen warten.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und das wird einfach alles verzögern. Und das wollen wir nicht.

Entsperren des Postgres Lock Managers. Bruce Momjian

In Postgres gibt es Möglichkeiten, um zu erkennen, wann das passiert. Und wenn es geschieht, erhalten Sie einen solchen Fehler. Daraus wird klar, dass ein bestimmter Prozess auf einen SHARE LOCK von einem anderen Prozess wartet, der von Prozess 711 blockiert wird. Dieser Prozess wartete darauf, dass ein SHARE LOCK für eine bestimmte Transaktions-ID gewährt wird und wurde von einem anderen Prozess blockiert. Daher ist hier eine Deadlock-Situation gegeben.

Entsperren des Postgres Lock Managers. Bruce Momjian

Gibt es auch dreiseitige Deadlocks? Ist das möglich? Ja.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wir geben diese Zahlen in die Tabelle ein. Wir ändern 40 auf 40, wir erstellen die Sperre.

Entsperren des Postgres Lock Managers. Bruce Momjian

Ändern wir 60 auf 61, 80 auf 81.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und dann ändern wir 80, und dann – bam!

Entsperren des Postgres Lock Managers. Bruce Momjian

Und 714 wartet jetzt auf 715. 716 wartet auf 715. Mit dem lässt sich schon nichts mehr machen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Hier sind es nicht mehr zwei Personen, hier sind es bereits drei. Ich will etwas von dir, dieser will etwas vom dritten, und der dritte will etwas von mir. Und wir befinden uns in einem dreiseitigen Erwartungszustand, weil wir alle darauf warten, dass die andere Person das beendet, was sie tun sollte.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und Postgres weiß, bei welcher Zeile das passiert. Daher wird er Ihnen die folgende Nachricht anzeigen, die zeigt, dass Sie ein Problem haben, bei dem drei Eingaben sich gegenseitig blockieren. Und es gibt keine Einschränkungen. Das kann der Fall sein, wenn 20 Einträge sich gegenseitig blockieren.

Entsperren des Postgres Lock Managers. Bruce Momjian

Das nächste Problem ist serializable.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn eine spezielle serializable Sperre.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und wir kommen zurück zu 719. Es hat eine ganz normale Ausgabe.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und Sie können klicken, um eine Transaktion aus serializable zu erstellen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und Sie verstehen, dass Sie jetzt eine andere Art von Sperre haben – das bedeutet serializable.

Entsperren des Postgres Lock Managers. Bruce Momjian

Entsperren des Postgres Lock Managers. Bruce Momjian

Und deshalb haben wir eine neue Art von Sperre, die SARieadLock genannt wird, die eine serielle Sperre ist und das Einfügen von Seriennummern ermöglicht.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und außerdem können Sie einzigartige Indizes einfügen.

Entsperren des Postgres Lock Managers. Bruce Momjian

In dieser Tabelle haben wir einzigartige Indizes.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn ich hier also die Zahl 2 eingebe, habe ich 2. Aber ganz oben füge ich noch eine 2 ein. Und Sie können sehen, dass 721 eine exklusive Sperre hat. Aber jetzt wartet 722, bis 721 seinen Vorgang abgeschlossen hat, denn es kann die 2 nicht einfügen, solange es nicht weiß, was mit 721 passiert.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und wenn wir eine Subtransaktion durchführen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Hier haben wir 723.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wenn wir den Punkt speichern und dann aktualisieren, erhalten wir eine neue Transaktions-ID. Das ist ein weiteres Verhaltensmerkmal, das Sie kennen müssen. Wenn wir das zurückgeben, verschwindet die Transaktions-ID. 724 verschwindet. Aber jetzt haben wir 725.

Was ich hier versuche, ist, Ihnen Beispiele für ungewöhnliche Sperren zu zeigen, die Sie finden können: sei es serialisierbare Sperren oder SAVEPOINT – das sind verschiedene Arten von Sperren, die in der Sperrtabelle erscheinen werden.

Entsperren des Postgres Lock Managers. Bruce Momjian

Es handelt sich um die Erstellung expliziter Sperren, wo pg_advisory_lock verwendet wird.

Entsperren des Postgres Lock Managers. Bruce Momjian

Sie sehen, dass der Sperrtyp hier als advisory aufgeführt ist. Und hier steht in Rot 'advisory'. Und Sie können gleichzeitig mit pg_advisory_unlock so eine Sperre aufheben.

Entsperren des Postgres Lock Managers. Bruce Momjian

Zum Abschluss möchte ich Ihnen noch eine sehr interessante Sache zeigen. Ich werde eine weitere Ansicht erstellen. Aber ich werde die Tabelle pg_locks mit der Tabelle pg_stat_activity verbinden. Und warum möchte ich das tun? Weil ich dadurch alle aktuellen Sitzungen sehen kann und welche Locks sie erwarten. Das ist ziemlich spannend, wenn wir die Locks-Tabelle und die Anfragen-Tabelle zusammenführen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und hier erstellen wir pg_stat_view.

Entsperren des Postgres Lock Managers. Bruce Momjian

Wir aktualisieren die Zeile um eins. Hier sehen wir 724. Dann aktualisieren wir unsere Zeile auf drei. Und was sehen Sie hier jetzt? Das sind die Anfragen, d.h. Sie sehen die gesamte Liste der Anfragen, die in der linken Spalte aufgeführt sind. Auf der rechten Seite sehen Sie die Locks und was sie erzeugen. Das könnte für Sie verständlicher sein, sodass Sie nicht jedes Mal zu jeder Sitzung zurückkehren müssen, um zu sehen, ob Sie sich anschließen sollten oder nicht. Das erledigt sich von selbst.

Eine weitere Funktion, die sehr nützlich ist – das ist pg_blocking_pids. Sie haben wahrscheinlich noch nie davon gehört. Was macht sie? Sie ermöglicht es uns zu sagen, dass für diese Sitzung 11740, welche spezifischen Prozess-IDs erwartet werden. Und Sie können sehen, dass 11740 724 erwartet. Und 724 steht ganz oben. 11306 ist Ihre Prozess-ID. Im Grunde geht diese Funktion durch Ihre Sperrtabelle. Ich weiß, dass es ein bisschen kompliziert ist, aber Sie schaffen es, das zu verstehen. Im Prinzip durchläuft diese Funktion diese Sperrtabelle und versucht herauszufinden, wo sich diese Prozess-ID befindet, unter Berücksichtigung der Sperren, auf die sie wartet. Sie versucht auch zu berechnen, welche Prozess-ID der Prozess hat, der auf die Sperre wartet. Daher können Sie diese Funktion ausführen. pg_blocking_pids.

Und das kann sehr nützlich sein. Wir haben das erst seit Version 9.6 hinzugefügt, also ist diese Funktion erst 5 Jahre alt, aber sie ist sehr, sehr nützlich. Das Gleiche gilt für die zweite Anfrage. Sie zeigt genau das, was wir sehen müssen.

Entsperren des Postgres Lock Managers. Bruce Momjian

Das ist, worüber ich mit Ihnen sprechen wollte. Und wie ich es erwartet habe, haben wir unsere gesamte Zeit genutzt, da es so viele Folien gab. Die Folien sind zum Herunterladen verfügbar. Ich möchte mich bei Ihnen bedanken, dass Sie hier waren. Ich bin sicher, dass Ihnen der Rest der Konferenz gefallen wird, vielen Dank!

Fragen:

Wenn ich versuche, Zeilen zu aktualisieren, während eine zweite Sitzung versucht, die gesamte Tabelle zu löschen. Soweit ich verstehe, sollte es so etwas wie einen Intent-Lock geben. Gibt es das in Postgres?

Entsperren des Postgres Lock Managers. Bruce Momjian

Lassen Sie uns ganz von vorne anfangen. Vielleicht erinnern Sie sich, dass wir, wenn Sie irgendetwas tun, zum Beispiel ein SELECT, einen AccessShareLock vergeben. Und das verhindert das Löschen der Tabelle. Wenn Sie also eine Zeile in der Tabelle aktualisieren oder löschen möchten, kann jemand die gesamte Tabelle nicht gleichzeitig löschen, weil Sie diesen AccessShareLock über die gesamte Tabelle und über die Zeile halten. Und sobald Sie fertig sind, können sie sie löschen. Aber solange Sie etwas dort ändern, können sie das nicht tun.

Lassen Sie es uns noch einmal betrachten. Lassen Sie uns zum Beispiel über das Löschen sprechen. Und Sie sehen, dass auf der Zeile ein exklusiver Lock über die gesamte Tabelle besteht.

Wird das wie ein exklusives Lock aussehen, richtig?

Ja, das sieht danach aus. Ich verstehe, was Sie meinen. Sie sagen, dass ich, wenn ich ein SELECT ausführe, ein ShareExclusive bekomme, und dann dieses in einen Row Exclusive umwandele. Wird das ein Problem sein? Überraschenderweise verursacht das jedoch kein Problem. Es scheint, als würde dies den Lock-Level erhöhen, aber tatsächlich habe ich einen Lock, der das Löschen verhindert. Und jetzt, wenn ich diesen Lock mächtiger mache, verhindert er weiterhin das Löschen. Daher ist es nicht so, als würde ich nach oben gehen. Das heißt, er hat das auch auf der niedrigeren Ebene verhindert, sodass er, wenn ich das Level erhöhe, immer noch das Löschen der Tabelle verhindert.

Ich verstehe, was Sie meinen. Hier gibt es keinen Fall einer Lock-Level-Erhöhung, wo Sie versuchen, eine Lock zu befreien, um eine mächtigere zu bekommen. Hier erhöht es einfach überall diese Verhinderung, daher gibt es keinen Konflikt. Aber das ist eine gute Frage. Vielen Dank, dass Sie sie gestellt haben!

Was müssen wir tun, um eine Deadlock-Situation zu vermeiden, wenn wir viele Sessions und eine große Anzahl von Benutzern haben?

Postgres erkennt automatisch Situationen von Deadlocks und entfernt automatisch eine der betroffenen Sitzungen. Der einzige Weg, um Deadlocks zu vermeiden, besteht darin, die Sperren in der gleichen Reihenfolge zu setzen. Wenn Sie also Ihre Anwendung betrachten, ist oft der Grund für Deadlocks… Stellen wir uns vor, ich möchte zwei verschiedene Dinge sperren. Eine Anwendung sperrt Tabelle 1, während eine andere Anwendung zuerst Tabelle 2 und dann Tabelle 1 sperrt. Der einfachste Weg, um Deadlocks zu vermeiden, besteht darin, sicherzustellen, dass die Sperren in allen Anwendungen in der gleichen Reihenfolge erfolgen. Dies beseitigt in der Regel 80 % der Probleme, weil unterschiedliche Personen diese Anwendungen schreiben. Wenn Sie sie in der gleichen Reihenfolge sperren, vermeiden Sie Deadlocks.

Vielen Dank für Ihre Ausführungen! Sie sprachen über vacuum full, und wenn ich richtig verstehe, dann verändert vacuum full die Reihenfolge der Datensätze in der einzelnen Speicherung, wodurch die aktuellen Datensätze unverändert bleiben. Aber warum benötigt vacuum full einen exklusiven Sperrzugriff und warum gibt es Konflikte mit Schreiboperationen?

Das ist eine gute Frage. Der Grund dafür ist, dass vacuum full die Tabelle belegt. Und wir erstellen im Wesentlichen eine neue Version der Tabelle. Die Tabelle wird neu sein. Das bedeutet, es wird eine vollkommen neue Version der Tabelle sein. Und das Problem ist, dass, wenn wir das tun, wir nicht möchten, dass die Leute diese Tabelle lesen, da wir möchten, dass sie die neue Tabelle sehen. Und daher hängt es mit der vorherigen Frage zusammen. Wenn wir gleichzeitig lesen könnten, könnten wir sie nicht verschieben und die Leute zur neuen Tabelle leiten. Wir müssten warten, bis jeder mit dem Lesen dieser Tabelle fertig ist, und deshalb ist es im Wesentlichen eine Situation mit exklusiver Sperrung.
Wir sagen einfach, dass wir von Anfang an blockieren, weil wir wissen, dass wir am Ende eine exklusive Sperre benötigen, um alle auf eine neue Kopie zu verschieben. Daher können wir das potenziell zulassen. Und wir tun dies mit gleichzeitiger Indizierung. Aber das ist viel komplizierter. Und das bezieht sich stark auf Ihre vorherige Frage zur exklusiven Sperre.

Ist es möglich, einen Lock-Timeout in Postgres hinzuzufügen? In Oracle kann ich zum Beispiel "select for update" schreiben und 50 Sekunden auf ein Update warten. Das war gut für die Anwendung. Aber in Postgres muss ich entweder sofort darauf zugreifen und gar nicht warten oder auf ein bestimmtes Zeitfenster warten.

Ja, Sie können einen Timeout für Ihre Sperren festlegen. Sie können auch den Befehl no way ausgeben, der … sein wird, wenn Sie die Sperre nicht sofort erhalten können. Also entweder Lock-Timeout oder etwas anderes, das Ihnen dies ermöglicht. Das geschieht nicht auf der syntaktischen Ebene. Es wird als Variable auf dem Server festgelegt. Manchmal kann dies nicht angewendet werden.

Könnten Sie den 75. Slide öffnen?

Ja.

Entsperren des Postgres Lock Managers. Bruce Momjian

Und meine nächste Frage lautet: Warum warten beide Aktualisierungsprozesse auf 703?

Das ist eine interessante Frage. Ich verstehe übrigens nicht, warum Postgres das macht. Aber als 703 erstellt wurde, erwartete es 702. Und wenn 704 und 705 erscheinen, scheint es so, als wüssten sie nicht, worauf sie warten, denn es gibt noch nichts. So funktioniert Postgres: Wenn Sie keine Sperre erhalten können, sagt es: "Warum sollten wir Sie überhaupt bearbeiten?", weil Sie ohnehin auf jemanden warten. Daher lassen wir es einfach im Leeren hängen, es wird das nicht einmal aktualisieren. Aber was ist hier passiert? Sobald 702 den Prozess abgeschlossen hat und 703 seine Sperre erhält, kehrt das System zurück. Und es sagt, dass wir jetzt zwei Personen haben, die auf etwas warten. Lassen Sie uns beide zusammen aktualisieren.

Ich weiß nicht, warum Postgres das so macht. Aber es gibt ein Problem, das als f… bezeichnet wird. Mir scheint, das ist kein Begriff auf Russisch. Das ist, wenn alle auf einen Lock warten, selbst wenn es 20 Instanzen gibt, die auf den Lock warten. Und plötzlich wachen sie alle gleichzeitig auf. Und alle versuchen zu reagieren. Aber das System sorgt dafür, dass alle auf 703 warten. Denn sie warten alle, und wir stellen sie sofort alle in eine Reihe. Und wenn ein neuer Anfrage aufkommt, die nach dieser entstanden ist, zum Beispiel 707, dann gibt es dort erneut eine Leere.

Und ich denke, das geschieht, damit man sagen kann, dass zu diesem Zeitpunkt 702 auf 703 wartet, während all jene, die danach kommen, keinen Eintrag in diesem Feld haben. Aber sobald der erste Wartende abspringt und alle, die in diesem Moment bis zur Aktualisierung gewartet haben, den gleichen Marker erhalten. Und deshalb scheint es mir, dass dies so gestaltet ist, damit wir die Anfragen in der richtigen Reihenfolge verarbeiten können.

Ich habe das immer als ein recht seltsames Phänomen betrachtet. Denn hier zum Beispiel listen wir sie überhaupt nicht auf. Aber ich denke, jedes Mal, wenn wir ein neues Lock vergeben, schauen wir uns alle an, die in der Warteschleife sind. Dann stellen wir sie alle in einer Reihe auf. Und jeder Neue, der kommt, gelangt nur dann in die Warteschlange, wenn die nächste Person fertig ist. Sehr gute Frage. Vielen Dank für Ihre Frage!

Es erscheint mir viel logischer, wenn 705 auf 704 wartet.

Das Problem ist folgendes: Technisch gesehen können Sie diesen oder jenen Prozess aufwecken. Und deshalb werden wir den einen oder den anderen aufwecken. Doch was passiert im System? Sie sehen, dass 703 seine eigene Transaktions-ID an der Spitze blockiert hat. So funktioniert Postgres. Und 703 blockiert seine eigene Transaktions-ID, also wird, wenn jemand wartet, er auf 703 warten. Im Grunde genommen wird 703 beendet. Und erst nach dessen Beendigung wird einer der Prozesse aufwachen. Und wir wissen nicht, welcher Prozess es sein wird. Dann verarbeiten wir alles schrittweise. Aber es ist unklar, welcher Prozess zuerst aufwacht, denn es könnte jeder dieser Prozesse sein. Im Grunde hatten wir einen Planer, der sagte, dass wir jetzt jeden dieser Prozesse aufwecken könnten. Wir wählen einfach einen zufällig aus. Daher müssen beide markiert werden, weil wir jeden von ihnen aufwecken können.

Das Problem ist, dass wir eine CP-Unendlichkeit haben. Daher ist es durchaus möglich, dass wir einen späteren Prozess wecken können. Wenn wir also beispielsweise einen späteren Prozess wecken, erwarten wir den, der gerade eine Sperrung erhalten hat, weshalb wir nicht genau bestimmen, wer zuerst geweckt wird. Wir schaffen einfach eine solche Situation, und das System wird sie in zufälliger Reihenfolge wecken.

Es gibt Artikel über Locks von Yegor Rogov. Schaut mal, die sind auch interessant und nützlich. Das Thema ist natürlich extrem komplex. Vielen Dank, Bruce!

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster