Entsperrung des Postgres Lock Managers. Bruce Momjian

Entschlüsselung des Berichts von 2020 von Bruce Momjian "Entsperrung des Postgres Lock Managers".

Entsperrung des Postgres Lock Managers. Bruce Momjian

(Hinweis: Alle SQL-Abfragen aus den Folien können Sie über diesen Link erhalten: http://momjian.us/main/writings/pgsql/locking.sql)

Hallo! Es ist großartig, wieder hier in Russland zu sein. Ich entschuldige mich dafür, dass ich im letzten Jahr nicht kommen konnte, aber Ivan und ich haben in diesem Jahr große Pläne. Ich hoffe, dass ich viel öfter hier sein werde. Ich liebe es, nach Russland zu kommen. Ich werde Tyumen und Tver besuchen. Ich freue mich sehr, dass ich die Möglichkeit habe, diese Städte zu besuchen.

Ich heiße Bruce Momjian. Ich arbeite bei EnterpriseDB und beschäftige mich seit über 23 Jahren mit Postgres. Ich lebe in Philadelphia, USA. Ich reise ungefähr 90 Tage im Jahr und besuche etwa 40 Konferenzen. Mein 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 sich auch etwa 30 Präsentationen. Außerdem gibt es Videos und eine große Anzahl an Blogeinträgen, über 500. Das ist eine ziemlich informative Ressource. Wenn Sie an diesem Material interessiert sind, lade ich Sie ein, es zu nutzen.

Früher war ich Dozent, Professor, bevor ich begann, mit Postgres zu arbeiten. Ich freue mich sehr, Ihnen jetzt das erzählen zu können, was ich Ihnen gleich vorstellen werde. Das ist eine meiner interessantesten Präsentationen. Diese Präsentation enthält 110 Folien. Wir beginnen mit einfachen Dingen, und gegen Ende wird die Präsentation immer komplizierter und komplexer.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Das ist ein ziemlich unangenehmes Thema. Locking ist kein besonders beliebtes Thema. Wir möchten, dass es irgendwie verschwindet. Es ist wie der Gang zum Zahnarzt.

Entsperrung des Postgres Lock Managers. Bruce Momjian

  1. Locking ist ein Problem für viele Menschen, die mit Datenbanken arbeiten, in denen mehrere Prozesse gleichzeitig ausgeführt werden. Sie benötigen Locking. Das bedeutet, dass ich Ihnen heute die Grundlagen des Lockings vermitteln werde.
  2. Transaktions-IDs. Das ist der etwas langweilige Teil der Präsentation, aber sie müssen verstanden werden.
  3. Als nächstes werden wir über die Arten von Locking sprechen. Das ist ein ziemlich technischer Teil.
  4. Und dann werden wir einige Beispiele für Lockings anführen. Das wird ziemlich anspruchsvoll.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Lassen Sie uns über Lockings sprechen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Die Terminologie ist bei uns ziemlich komplex. Wie viele von Ihnen wissen, woher dieser Ausschnitt stammt? Zwei Personen. Es stammt aus einem Spiel, das "Kolosales Abenteuer in der Höhle" heißt. Es war ein textbasiertes Computerspiel in den 80er Jahren, so glaube ich. Man musste in die Höhle, das Labyrinth gehen, und die Texte änderten sich, aber der Inhalt blieb dabei jeweils ungefähr gleich. So erinnere ich mich an dieses Spiel.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und hier sehen wir die Bezeichnungen der Sperren, die wir von Oracle erhalten haben. Wir verwenden sie.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Hier sehen wir Begriffe, die mich verwirren. Zum Beispiel, SHARE UPDATE EXCLUSIVE. Dann SHARE RAW EXCLUSIVE. Um ehrlich zu sein, sind diese Bezeichnungen nicht sehr klar. Wir werden versuchen, sie detaillierter zu betrachten. Einige enthalten das Wort „share“, was bedeutet – sich abzuspalten. Einige enthalten das Wort „exclusive“ – exklusiv. In einigen befinden sich beide Wörter. Ich möchte mit der Funktionsweise dieser Sperren beginnen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und auch das Wort „Zugriff“ – access ist sehr wichtig. Und das Wort „row“ – Zeile. D.h. Zugriffverteilung, Zeilenverteilung.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Ein weiteres Problem, das man in Postgres verstehen muss, das ich leider nicht in meinem Vortrag behandeln kann, ist MVCC. Ich habe eine separate Präsentation zu diesem Thema auf meiner Website. Und wenn Sie denken, dass diese Präsentation kompliziert ist, dann ist MVCC wahrscheinlich die komplizierteste. Und wenn Sie interessiert sind, können Sie sie auf der Website anschauen. Sie können sich das Video ansehen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Ein weiterer Punkt, den wir verstehen müssen, sind die Transaktions-IDs. Viele Transaktionen können nicht ohne einzigartige IDs arbeiten. Hier haben wir eine Erklärung, was eine Transaktion ist. In Postgres gibt es zwei Systeme zur Nummerierung von Transaktionen. Ich weiß, dass das keine sehr schöne Lösung ist.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Bitte beachten Sie auch, dass die Folien ziemlich komplex zu verstehen sein werden, daher sollten Sie besonders auf das achten, was rot hervorgehoben ist.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Wir sehen. 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 dem rosa hervorgehobenen Link folgen 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 wird keine Farben enthalten, aber zumindest werden wir sie sehen können.

Entsperrung des Postgres Lock Managers. Bruce Momjian

In diesem Fall sehen wir die ID der Transaktion. Das ist die Nummer, die wir ihr zugewiesen haben. Es gibt auch noch einen anderen Typ von 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 die ID einer Transaktion, die keine dauerhaften Werte enthält. Wenn ich beispielsweise den SELECT-Befehl ausführe, werde ich wahrscheinlich nicht die Datenbank ändern und nichts sperren. Daher vergeben wir beim Ausführen eines einfachen SELECTs dieser Transaktion keine dauerhafte ID. Wir geben ihr nur eine virtuelle ID.

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wenn ich also eine Abfrage ausführe, zeigt sie an, dass die Backend-ID 2 ist.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wenn ich eine Reihe solcher Transaktionen ausführe, 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. ausführe.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Bitte beachten Sie, dass hier zwei Spalten vorhanden sind. Links sehen wir die virtuelle Transaktions-ID – 2/12. Rechts haben wir die dauerhafte Transaktions-ID. Und dieses Feld ist leer. Diese Transaktion modifiziert die Datenbank nicht. Deshalb weise ich ihr keine dauerhafte Transaktions-ID zu.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Sobald ich den Befehl analysieren (ANALYZE) ausführe, gibt mir die gleiche Abfrage eine dauerhafte Transaktions-ID. Sehen Sie, wie sich das geändert hat. Früher hatte ich diese ID nicht, jetzt ist sie erschienen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Hier ist also eine weitere Abfrage, eine weitere Transaktion. Die virtuelle Transaktionsnummer ist 2/13. Und wenn ich nach der dauerhaften Transaktions-ID frage, werde ich sie erhalten, sobald ich die Abfrage ausgeführt habe.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wir kommen zum dritten Abschnitt. Hier gehen wir einfach die verschiedenen Arten von Sperren in Postgres durch. Es ist nicht besonders spannend. Der letzte Abschnitt wird viel interessanter sein. Aber wir müssen die grundlegenden Dinge betrachten, denn sonst verstehen wir nicht, was als Nächstes kommt.

Wir werden diesen Abschnitt durchgehen, wir werden uns jeden Sperrtyp ansehen. Und ich werde Ihnen Beispiele zeigen, wie sie eingerichtet werden, wie sie funktionieren, und Ihnen einige Abfragen zeigen, die Sie verwenden können, um zu sehen, wie die Sperren in Postgres funktionieren.

Entsperrung 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 haben wir pg_lock in rot markiert. Pg_lock ist eine Systemtabelle, die uns sagt, welche Sperren derzeit in Postgres verwendet werden.

Es ist jedoch sehr schwierig für mich, Ihnen pg_lock alleine zu zeigen, da es ziemlich komplex ist. Daher habe ich eine Ansicht erstellt, die pg_locks zeigt. Und sie führt auch einige Arbeiten für mich aus, die es mir ermöglichen, besser zu verstehen. Das heißt, sie schließt meine Sperren, meine eigene Sitzung usw. aus. Das ist einfach standardmäßiges SQL und es ermöglicht mir, Ihnen besser zu zeigen, was passiert.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Ein weiteres Problem ist, dass diese Ansicht sehr umfassend ist, daher muss ich eine zweite erstellen – lockview2.

Entsperrung des Postgres Lock Managers. Bruce Momjian Und sie zeigt mir weitere Spalten aus der Tabelle an. Und noch eine, die mir die restlichen Spalten zeigt. Das ist ziemlich komplex, daher habe ich versucht, es so einfach wie möglich darzustellen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Und wenn wir die Sperrung explizit festlegen wollen, führen wir den Befehl „lock table“ aus. Und das wird eindeutig gesperrt, d. h. im ACCESS SHARE-Modus führen wir lock table aus. Und wenn ich PSQL im Hintergrund ausführe, starte ich auf diese Weise eine zweite Sitzung aus meiner ersten Sitzung. Was mache ich hier? Ich gehe zu einer anderen Sitzung und sage ihr: „Zeig mir die lockview für diese Anfrage“. Und hier habe ich AccessShareLock in dieser Tabelle. Das ist genau das, was ich angefordert habe. Und er sagt, dass die Sperrung zugewiesen wurde. Ganz einfach.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wenn ich den Befehl „SELECT“ ausführe, ist das eine implizite (explizite) Möglichkeit, um AccessShareLock anzufordern. Daher gebe ich meine Tabelle frei und führe die Abfrage aus, und die Abfrage gibt mehrere Zeilen zurück. Und in einer der Zeilen sehen wir AccessShareLock. Somit ruft SELECT AccessShareLock in der Tabelle auf. Und es gibt praktisch keinen Konflikt, weil es sich um eine Low-Level-Sperre handelt.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Und das ist eine Sperre, die praktisch keinen Konflikt mit anderen hat. Alles, was sie tut, ist einfach, dass sie uns nicht erlaubt, die Tabelle zurückzusetzen, während wir sie auswählen. Das macht Sinn. D. h. wenn wir eine Tabelle auswählen, verschwindet sie in diesem Moment, das ist falsch, deshalb. AccessShare – das ist eine Low-Level-Sperre, die uns sagt: "Löschen Sie diese Tabelle nicht, während ich arbeite".. Im Grunde ist das alles, was sie tut.

Entsperrung des Postgres Lock Managers. Bruce Momjian

ROW SHARE – das ist eine Sperre, die etwas anders ist.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Lassen Sie uns ein Beispiel nehmen. SELECT ROW SHARE ist eine Art von Sperre für jede Zeile einzeln.So kann niemand sie löschen oder ändern, während wir sie betrachten.

Entsperrung des Postgres Lock Managers. Bruce MomjianWas macht SHARE LOCK? Wir sehen, dass die Transaktions-ID 681 für den SELECT-Befehl ist. 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, dass sie im exklusiven Modus blockiert wird. Alles, was sie tut, ist zu sagen, dass ich eine Zeile habe, die technisch irgendwo in der Tabelle blockiert ist. Aber sie sagt nicht, wo genau. Später werden wir das ausführlicher betrachten.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Die exklusive Sperre sagt explizit, dass sie exklusiv ist. Und wenn Sie eine Zeile in dieser Tabelle löschen, wird es so geschehen, wie Sie sehen können.

Entsperrung des Postgres Lock Managers. Bruce Momjian

SHARE EXCLUSIVE ist eine längere Sperre.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Das ist der ANALYZE-Befehl, der verwendet wird.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Mit SHARE LOCK können Sie explizit im Freigabemodus blockieren.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Sie können auch einen einzigartigen Index erstellen. Und dort sehen Sie SHARE LOCK, das Teil davon ist. Und es blockiert die Tabelle und setzt eine SHARE LOCK darauf.

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

Wenn ich einen einzigartigen Index concurrently erstelle, werde ich einen anderen Sperrtyp haben, denn wie Sie sich erinnern, verringert die Verwendung von concurrently Indizes die Anforderungen an die Sperrung. Und wenn ich eine normale Sperre, einen normalen Index verwende, verhindere ich so das Schreiben in den Index der Tabelle während seiner Erstellung. Wenn ich einen concurrently Index verwende, muss ich einen anderen Sperrtyp verwenden.

Entsperrung des Postgres Lock Managers. Bruce Momjian

SHARE ROW EXCLUSIVE kann auch explizit angegeben werden.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Hier sehen wir verschiedene Arten von Sperren.

Entsperrung des Postgres Lock Managers. Bruce Momjian

ACCESS EXCLUSIVE ist beispielsweise ein Sperrbefehl. Zum Beispiel, wenn Sie die Tabelle CLUSTER, bedeutet das, dass niemand dort schreiben kann. Und es blockiert nicht nur die Tabelle selbst, sondern auch die Indizes.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Das ist die zweite Seite der ACCESS EXCLUSIVE-Sperre, auf der wir konkret sehen, was sie in der Tabelle blockiert. Sie blockiert einzelne Zeilen der Tabelle, was ziemlich interessant ist.

Dies sind alle grundlegenden Informationen, die ich Ihnen geben wollte. Wir haben über Sperren gesprochen, über Transaktions-IDs, über virtuelle Transaktions-IDs und über permanente Transaktions-IDs.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und jetzt werden wir uns einige Beispiele für Sperren ansehen. Dies ist der spannendste Teil. Wir werden sehr interessante Fälle betrachten. Mein Ziel in dieser Präsentation ist es, Ihnen ein besseres Verständnis davon zu geben, was Postgres tatsächlich macht, wenn es versucht, verschiedene Dinge zu sperren. Ich denke, es kann sehr gut einzelne Teile sperren.

Lassen Sie uns bestimmte Beispiele betrachten.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Was passiert, wenn ich zwei weitere Zeilen einfüge? Jetzt haben wir drei Zeilen in unserer Tabelle. Ich habe eine Zeile eingefügt und das hier als Ausgabe erhalten. Und wenn ich noch zwei Zeilen einfüge, was ist hier ungewöhnlich? Es gibt etwas Seltsames, denn ich habe drei Zeilen zu dieser Tabelle hinzugefügt, aber ich habe immer noch zwei Zeilen in der Sperrtabelle. Und das ist im Wesentlichen das grundlegende Verhalten von Postgres.

Viele denken, dass wenn Sie in einer Datenbank 100 Zeilen sperren, Sie 100 Sperreinträge 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 das so machen, wird es nicht sehr gut funktionieren. Wenn Sie ein System verwendet haben, das Sperreinträge für jede einzelne Zeile erstellt, sehen Sie, dass das kompliziert ist. Denn Sie müssen sofort die Sperrtabelle definieren, die überlaufen kann, aber so funktioniert Postgres nicht.

Und auf dieser Folie ist es sehr wichtig, dass hier eindeutig gezeigt wird, dass es noch ein anderes System gibt, das innerhalb von MVCC arbeitet und einzelne Zeilen sperrt. Daher erstellt Postgres, wenn Sie Milliarden von Zeilen sperren, nicht eine Milliarde separater Sperrkommandos. Und das wirkt sich sehr positiv auf die Leistung aus.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wie sieht es mit dem Update aus? Ich aktualisiere gerade eine Zeile, und Sie werden vielleicht bemerken, dass er sofort zwei verschiedene Operationen durchgeführt hat. Er hat die Tabelle gleichzeitig gesperrt, aber auch den Index gesperrt. Und er musste den Index sperren, weil es eindeutige Einschränkungen in dieser Tabelle gibt. und wir wollen sicherstellen, dass ihn niemand ändert, deshalb sperren wir ihn.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Was passiert, wenn ich zwei Zeilen aktualisieren möchte? Und wir sehen, dass es sich gleich verhält. Wir führen doppelt so viele Aktualisierungen durch, aber die gleiche Anzahl von Sperrzeilen.

Wenn Sie sich fragen, wie Postgres das macht, müssen Sie sich meine Vorträge über MVCC anhören, um zu erfahren, wie Postgres intern diese Zeilen markiert, die er ändert. Und Postgres hat eine Methode, mit der er das macht, aber er macht es nicht auf Tabellen-Sperr-Ebene, sondern auf einer niedrigeren und effizienteren Ebene.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wenn ich etwas löschen möchte? Wenn ich zum Beispiel eine Zeile lösche und ich immer noch meine zwei anfänglichen Sperren habe, und selbst wenn ich sie alle löschen möchte, bleiben sie trotzdem vorhanden.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wenn ich zum Beispiel 1.000 Zeilen einfügen möchte und dann entweder löschen oder 1.000 Zeilen hinzufügen möchte, werden die einzelnen Zeilen, die ich hinzufüge oder ändere, hier nicht gespeichert. Sie werden auf einer niedrigeren Ebene innerhalb der Zeile selbst gespeichert. Und während des Vortrags über MVCC habe ich das detailliert besprochen. Aber es ist sehr wichtig, wenn Sie Sperren analysieren, sicherzustellen, dass Sie eine Sperre auf Tabellenebene haben und dass Sie hier nicht sehen, wie einzelne Zeilen aufgezeichnet werden.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wie sieht es mit einer expliziten Sperre aus?

Entsperrung 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, habe ich immer noch zwei Sperreinträge.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wir erstellen keine separaten Einträge für jede einzelne Zeile. Denn das würde die Leistung beeinträchtigen, da es vielleicht zu viel davon gibt. Und wir könnten in einer unangenehmen Situation landen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und dasselbe gilt, wenn wir shared machen, können wir das auf alle 30 Mal tun.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Und Sie können bemerken, dass oben – das ist eine ShareLock, und unten – das ist eine ExclusiveLock. Und beide Transaktionen wurden erstellt.

Und Sie sollten mein Referat über MVCC anhören, um zu verstehen, wie das funktioniert. Aber das ist eine Veranschaulichung des, was Sie gleichzeitig tun können, d.h. SELECT und UPDATE gleichzeitig durchführen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wenn Sie versuchen, gleichzeitig zwei Updates auf derselben Zeile auszuführen, wird es blockiert. Und denken Sie daran, ich sagte, dass der Lesende den Schreibenden nicht blockiert, der Schreibende aber den Lesenden blockiert, und ein Schreibender blockiert einen anderen Schreibenden. Das heißt, wir können nicht zulassen, dass zwei Personen gleichzeitig dieselbe Zeile aktualisieren. Einer muss warten, bis der andere fertig ist.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und um das zu veranschaulichen, werde ich mir die Lockdemo-Tabelle ansehen. Und wir werden uns eine Zeile anschauen. Bei der Transaktion 698.

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

Entsperrung 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 die diesen Wert auf 3 geändert hat. Und wenn Sie bemerken, hat sich der obere selbst blockiert, der 699 ist. Aber 3/112 hat keine Sperre bereitgestellt. In der Spalte Lock_mode steht, dass er wartet. Er wartet auf 699. Und wenn Sie schauen, wo 699 ist, ist es darüber. Und was hat die erste Sitzung gemacht? Sie hat eine exklusive Sperre auf ihrer eigenen Transaktions-ID gesetzt. So macht es Postgres. Es blockiert die eigene Transaktions-ID. Und wenn Sie warten möchten, bis jemand bestätigt oder abbricht, müssen Sie warten, bis es eine wartende Transaktion gibt. Deshalb können wir diese seltsame Zeile sehen.

Lassen Sie uns noch einmal hinschauen. Links sehen wir unsere Prozess-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 sagt sie, dass sie die Transaktions-ID blockiert. Aber beachten Sie, dass in allen Zeilen unten 'relation' steht. Und deshalb haben Sie zwei Arten von Sperren in der Tabelle. Es gibt die Sperre 'relation'. Und es gibt auch die Sperre 'transactionid', wo Sie selbst blockieren. Das ist genau das, was in der ersten Zeile oder ganz unten passiert, wo transactionid steht, wo wir warten, dass 699 seine Operation abschließt.

Ich schaue mir an, was hier passiert. Und hier passieren gleichzeitig zwei Dinge. Sie schauen sich die Sperre nach der Transaktions-ID in der ersten Zeile an, die sich selbst blockiert. Und sie blockiert sich selbst, um die Leute warten zu lassen.

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und im lock_type sehen Sie tuple-Nummern.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Aber tatsächlich ist es 0/10, weil auf die Durchführung dieser Operation gewartet wird. Wir haben die Möglichkeit zu sehen, dass dies die Zeile ist, auf die ich warte, um sie zu bestätigen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Sobald wir es bestätigt und auf Commit geklickt haben und das Update abgeschlossen ist, ist das, was wir wieder erhalten. Transaktion 700 ist die einzige Sperre, sie wartet auf niemanden mehr, da sie bereits kommittiert wurde. Sie wartet nur 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 allen erlaubten Tabellen hat.

Entsperrung 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 Abfrage verstehen. Aber es gibt uns eine klarere Sicht darauf, was vor sich geht.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Was wäre, wenn wir drei gleichzeitige Updates durchführen und sagen, dass die Reihe jetzt drei beträgt. Und wir ändern 3 in 4.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und alles wird klar. Welche ist die erste Reihe? Das ist 702. Das ist die Transaktions-ID, die diesen Wert ursprünglich festgelegt 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. Dort haben wir die Sperre der Transaktions-ID. Und es gibt 5 Transaktionssperren-IDs.

Und wenn Sie sich 704 und 705 ansehen, steht dort noch nichts geschrieben, weil sie noch nicht wissen, was passiert. Sie schreiben einfach, dass sie keine Ahnung haben, was passiert. Und sie werden einfach schlafen gehen, weil sie warten, dass jemand fertig ist und sie weckt, wenn es die Gelegenheit gibt, die Reihe zu ändern.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Sobald die erste Transaktion genehmigt ist, können Sie hier sehen, wie die Hierarchie funktioniert. Und jetzt wird alles klar. Sie werden alle klar. Und sie sind tatsächlich immer noch im Warten.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Das ist, was passiert. 702 wird festgeschrieben. Und jetzt erhält 703 diese Zeilen-Sperre, während 704 darauf wartet, dass 703 festgeschrieben wird. Auch 705 wartet darauf. Und wenn das alles abgeschlossen ist, reinigen sie sich selbst. Ich möchte darauf hinweisen, dass sich alle in einer Warteschlange anstellen. Das ähnelt sehr der Situation mit einem Stau, wenn alle auf das erste Auto warten. Das erste Auto hat angehalten, und alle stellen sich in eine lange Reihe. Dann fährt es weiter, dann kann das nächste Auto vorfahren und seine Sperre erhalten usw.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wenn Ihnen das nicht kompliziert genug erschien, sprechen wir jetzt über Deadlocks. Ich weiß nicht, wer von Ihnen schon einmal mit ihnen zu tun hatte. Es ist ein recht verbreitetes Problem in Datenbanksystemen. Aber Deadlocks sind der Fall, 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.

Zum Beispiel, wenn Ivan sagt: „Gib mir etwas“, und ich sage: „Nein, ich gebe dir das nur, wenn du mir etwas anderes gibst“. Und er sagt: „Nein, ich gebe es dir nicht, wenn du mir nichts gibst“. Dann befinden wir uns in einer Deadlock-Situation. Ich bin mir sicher, dass Ivan das nicht tun würde, aber Sie verstehen den Sinn: Wir haben zwei Personen, die etwas erhalten möchten, und sie sind nicht bereit, es zu geben, solange die andere Person ihnen nicht gibt, was sie wollen. Und es gibt keine Lösung.

Im Wesentlichen muss Ihre Datenbank dies erkennen. Und dann müssen Sie eine der Sitzungen schließen oder abbrechen, denn sonst bleiben sie dort für immer. Und wir sehen das in Datenbanken, wir sehen das in Betriebssystemen. Und an allen Orten, an denen wir parallele Prozesse haben, kann so etwas vorkommen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Dann werde ich 80 auf 81 und 50 auf 51 ändern.

Entsperrung des Postgres Lock Managers. Bruce Momjian

So wird es aussehen. Daher hat 710 eine Zeilen-Sperre, während 711 auf eine Bestätigung wartet. Wir haben das gesehen, als wir aktualisierten. 710 ist der Eigentümer unserer Zeile. Und 711 wartet darauf, dass 710 die Transaktion abschließt.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Es steht sogar dabei, an welcher Zeile unser Deadlock auftritt. Und dort fängt es an, merkwürdig zu werden.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Jetzt aktualisieren wir 80 auf 80.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und hier beginnt das Deadlock. 710 wartet auf eine Rückmeldung von 711, während 711 auf 710 wartet. Das wird nicht gut enden. Und es gibt keinen Ausweg. Sie werden aufeinander warten.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

In Postgres gibt es Möglichkeiten zu erkennen, wann das passiert. Und wenn das passiert, erhalten Sie diese Fehlermeldung. Daraus wird klar, dass ein Prozess auf einen SHARE LOCK von einem anderen Prozess wartet, das heißt, der von Prozess 711 blockiert wird. Und dieser Prozess wartete darauf, einen SHARE LOCK für eine bestimmte Transaktions-ID zu erhalten und wurde von einem anderen Prozess blockiert. Daher handelt es sich hier um eine Deadlock-Situation.

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wir ändern 60 auf 61, 80 auf 81.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und dann ändern wir 80 und dann – boom!

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und 714 wartet jetzt auf 715. 716 wartet auf 715. Und damit kann man nichts mehr machen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Hier sind nicht nur zwei Personen, hier sind schon drei Personen. Ich will etwas von dir, dieser will etwas von der dritten Person, und die dritte Person will etwas von mir. Und wir kommen in eine dreiseitige Warteschlange, weil wir alle darauf warten, dass die andere Person das, was sie tun soll, abschließt.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und Postgres weiß, in welcher Zeile das passiert. Deshalb wird er Ihnen die nächste Meldung geben, die zeigt, dass Sie ein Problem haben, bei dem drei Prozesse sich gegenseitig blockieren. Und hier gibt es keine Einschränkungen. Das kann in einem Szenario passieren, in dem 20 Datensätze sich gegenseitig blockieren.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Das nächste Problem ist serializable.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wenn eine spezielle serializable Sperre auftritt.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wir kehren zu 719 zurück. Es gibt eine ganz normale Ausgabe.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und Sie können klicken, um die Transaktion aus serializable durchzuführen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und Sie erkennen, dass Sie jetzt eine andere Art von Sperre haben – das ist SA, was serializable bedeutet.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Entsperrung des Postgres Lock Managers. Bruce Momjian

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und Sie können auch eindeutige Indizes einfügen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

In dieser Tabelle haben wir eindeutige Indizes.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wenn ich also die Zahl 2 hier eingebe, dann habe ich 2. Aber ganz oben füge ich noch einmal 2 hinzu. Und Sie können sehen, dass 721 eine exklusive Sperre hat. Aber jetzt wartet 722 darauf, dass 721 seine Operation abschließt, weil es die 2 nicht einfügen kann, bis es weiß, was mit 721 geschieht.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wenn wir eine Subtransaktion machen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Hier haben wir 723.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Wenn wir den Punkt beibehalten und ihn dann aktualisieren, erhalten wir eine neue Transaktions-ID. Das ist ein weiteres Verhaltensmerkmal, das Sie wissen sollten. Wenn wir dies zurückgeben, geht die Transaktions-ID weg. 724 verschwindet. Aber jetzt erscheint 725.

Und was versuche ich hier zu tun? Ich versuche, Ihnen Beispiele für ungewöhnliche Sperren zu zeigen, die Sie finden können: ob es sich um serialisierbare Sperren oder SAVEPOINT handelt – das sind verschiedene Arten von Sperren, die in der Sperrtabelle erscheinen werden.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Es handelt sich um das Erstellen expliziter (statischer) Sperren, bei denen pg_advisory_lock verwendet wird.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und 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 sperren.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und zum Abschluss möchte ich Ihnen noch eine geniale Sache zeigen. Ich werde eine weitere Art erstellen. Aber ich werde die Tabelle pg_locks mit der Tabelle pg_stat_activity verbinden. Und warum möchte ich das tun? Weil ich mir damit alle aktuellen Sitzungen ansehen und sehen kann, auf welche Sperren sie warten. Das ist ziemlich interessant, wenn wir die Sperrtabelle und die Abfragetabelle zusammenbringen.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und hier erstellen wir pg_stat_view.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und wir aktualisieren eine Zeile um eins. Und hier sehen wir 724. Dann aktualisieren wir unsere Zeile auf drei. Was sehen Sie hier jetzt? Das sind die Abfragen, d.h. Sie sehen die gesamte Liste der Abfragen, die in der linken Spalte aufgeführt sind. Und dann sehen Sie auf der rechten Seite die Sperren und was sie erzeugen. Das kann 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 müssen oder nicht. Das übernehmen für uns.

Eine weitere Funktion, die sehr nützlich ist – das ist pg_blocking_pids. Sie haben wahrscheinlich noch nie von ihr gehört. Was macht sie? Sie erlaubt uns zu sagen, dass für diese Sitzung 11740, welche spezifischen Prozess-IDs sie erwartet. Und Sie können sehen, dass 11740 724 erwartet. Und 724 steht ganz oben. Und 11306 ist Ihre Prozess-ID. Grundsätzlich durchläuft diese Funktion Ihre Sperrtabelle. Und ich weiß, dass das ein bisschen kompliziert ist, aber Sie verstehen es. Im Grunde genommen durchläuft diese Funktion diese Sperrtabelle und versucht zu finden, wo sich diese Prozess-ID befindet, und berücksichtigt dabei die Sperren, auf die sie wartet. Sie versucht auch herauszufinden, welche Prozess-ID der Prozess hat, der auf die Sperren wartet. Daher können Sie diese Funktion ausführen. pg_blocking_pids.

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

Entsperrung des Postgres Lock Managers. Bruce Momjian

Das ist es, worüber ich mit Ihnen sprechen wollte. Und wie ich erwartet habe, haben wir unsere ganze Zeit genutzt, weil es eine so große Anzahl an Folien gab. Und die Folien sind zum Download verfügbar. Ich möchte Ihnen danken, dass Sie hier waren. Ich bin mir sicher, dass Ihnen der Rest der Konferenz gefallen wird, vielen Dank!

Fragen:

Zum Beispiel, wenn ich versuche, Zeilen zu aktualisieren, während eine zweite Sitzung versucht, die gesamte Tabelle zu löschen. So wie ich es verstehe, sollte es da etwas wie einen Intent Lock geben. Gibt es das in Postgres?

Entsperrung des Postgres Lock Managers. Bruce Momjian

Gehen wir zurück zum Anfang. Vielleicht erinnern Sie sich, dass wir, wenn Sie irgendetwas tun, zum Beispiel wenn Sie einen SELECT durchführen, ein AccessShareLock vergeben. Und das verhindert das Löschen der Tabelle. Wenn Sie also zum Beispiel eine Reihe in der Tabelle aktualisieren oder eine Reihe löschen möchten, kann jemand nicht gleichzeitig die gesamte Tabelle löschen, da Sie dieses AccessShareLock über der gesamten Tabelle und über der Reihe halten. Und sobald Sie fertig sind, können sie sie löschen. Aber solange Sie direkt etwas dort verändern, können sie das nicht tun.

Lassen Sie es uns noch einmal durchgehen. Lassen Sie uns zum Beispiel auf das Löschen eingehen. Und Sie sehen, dass über der Reihe ein exklusives Lock über der gesamten Tabelle liegt.

Das würde wie ein lock exclusive aussehen, richtig?

Ja, das sieht so aus. Ich verstehe, worüber Sie sprechen. Sie sagen, dass ich, wenn ich ein SELECT ausführe, ShareExclusive habe und es dann in den Zustand Row Exclusive übergehe, ob das ein Problem wird? Aber überraschenderweise verursacht das kein Problem. Es ist wie eine Erhöhung des Sperrgrades, aber im Wesentlichen habe ich einen Lock, der das Löschen verhindert. Und jetzt, wenn ich diesen Lock stärker mache, verhindert er immer noch das Löschen. Daher ist es nicht so, dass ich nach oben gehe. Das heißt, es hat das auch auf einem niedrigeren Niveau verhindert, darum, wenn ich es erhöhe, verhindert es immer noch das Löschen der Tabelle.

Ich verstehe, worüber Sie sprechen. Hier gibt es keinen Fall einer Erhöhung des Sperrgrades, wo Sie versuchen, eine Sperre aufzugeben, um eine stärkere einzuführen. Hier wird einfach überall diese Verhinderung erhöht, sodass es keinen Konflikt gibt. Aber das ist eine gute Frage. Vielen Dank, dass Sie sie gestellt haben!

Was müssen wir tun, um eine Situation mit Deadlocks zu vermeiden, wenn wir viele Sitzungen und eine große Anzahl von Benutzern haben?

Postgres erkennt automatisch Deadlock-Situationen. Und wird automatisch eine der Sitzungen beenden. Der einzige Weg, um Deadlocks zu vermeiden, besteht darin, die Sperren in der gleichen Reihenfolge anzuwenden. Daher, wenn Sie sich Ihre Anwendung anschauen, ist es oft die Ursache für Deadlocks ... Stellen wir uns vor, ich möchte zwei verschiedene Dinge sperren. Eine Anwendung sperrt Tabelle 1, und eine andere Anwendung sperrt 2, und dann Tabelle 1. Der einfachste Weg, Deadlocks zu vermeiden, besteht darin, Ihre Anwendung zu betrachten und sicherzustellen, dass die Sperrung in derselben Reihenfolge in allen Anwendungen erfolgt. Und das eliminiert in der Regel 80 % der Probleme, weil die unterschiedlichsten Menschen diese Anwendungen entwickeln. Und wenn Sie sie in derselben Reihenfolge sperren, kommen Sie nicht in die Deadlock-Situation.

Vielen Dank für Ihren Vortrag! Sie haben über Vacuum Full gesprochen und, wenn ich richtig verstehe, verändert Vacuum Full die Reihenfolge der Datensätze in der einzelnen Speicherung, sodass die aktuellen Datensätze unverändert bleiben. Aber warum erfordert Vacuum Full einen exklusiven Sperrzugriff und warum gibt es Konflikte mit Schreibvorgängen?

Das ist eine gute Frage. Der Grund dafür ist, dass vacuum full die Tabelle übernimmt. Wir erstellen im Grunde genommen eine neue Version der Tabelle. Die Tabelle wird also neu sein. Das bedeutet, dass es sich um eine völlig neue Version der Tabelle handeln wird. Und das Problem ist, dass wir nicht wollen, dass die Leute das lesen, während wir das tun, denn wir müssen sicherstellen, dass sie die neue Tabelle sehen. Deshalb hängt das mit der vorherigen Frage zusammen. Wenn wir gleichzeitig lesen könnten, könnten wir es nicht verschieben und die Leute auf die neue Tabelle umleiten. Wir müssten abwarten, bis alle mit dem Lesen dieser Tabelle fertig sind, und deshalb ist es im Wesentlichen eine exklusive Sperrsituation.
Wir sagen einfach, dass wir von Anfang an sperren, 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 lösen. Und wir machen das so mit gleichzeitiger Indizierung. Aber das ist viel komplizierter. Und das hat sehr viel mit Ihrer vorherigen Frage zur exklusiven Sperre zu tun.

Ist es möglich, einen Sperrzeitlimit in Postgres hinzuzufügen? In Oracle kann ich zum Beispiel 'select for update' schreiben und 50 Sekunden auf das Update warten. Das war gut für die Anwendung. Aber in Postgres muss ich das entweder sofort tun und überhaupt nicht warten, oder bis zu einem bestimmten Zeitpunkt warten.

Ja, Sie können einen Timeout für Ihre Sperren wählen. Sie können auch den Befehl 'no way' ausgeben, der …, wenn Sie die Sperre nicht sofort erhalten können. Also entweder lock timeout oder etwas anderes, das Ihnen das ermöglicht. Das wird nicht auf syntaktischer Ebene gemacht. Es wird als Variable auf dem Server eingestellt. Manchmal kann man das nicht verwenden.

Könnten Sie die Folie 75 öffnen?

Ja.

Entsperrung des Postgres Lock Managers. Bruce Momjian

Und meine Frage lautet: Warum warten beide Update-Prozesse auf 703?

Und das ist eine großartige Frage. Ich verstehe übrigens nicht, warum Postgres das macht. Als 703 erstellt wurde, erwartete es 702. Und als 704 und 705 erscheinen, scheint es, dass sie nicht wissen, auf was sie warten, denn es gibt noch nichts. Und Postgres macht es so: Wenn Sie keine Sperre erhalten können, schreibt es: „Was hat einen Sinn beim Verarbeiten von euch?“ weil ihr sowieso auf jemanden wartet. Daher lassen wir es einfach in der Luft hängen, es aktualisiert das überhaupt nicht. 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 warten. Und dann lass uns sie gemeinsam aktualisieren. Und wir geben an, dass beide warten.

Ich weiß nicht, warum Postgres das macht. Aber es gibt ein Problem, das f… genannt wird. Mir scheint, dass dies kein Begriff auf Russisch ist. Es ist, wenn alle auf eine Sperre warten, selbst wenn 20 Instanzen warten, die auf eine Sperre warten. Und plötzlich wachen sie alle gleichzeitig auf. Und alle beginnen zu versuchen, zu reagieren. Aber das System sorgt dafür, dass alle 703 erwarten. Weil sie alle warten, und wir stellen sie sofort alle in eine Schlange. Und wenn eine neue Anfrage erscheint, die danach erstellt wurde, zum Beispiel 707, dann wird es dort wieder Leere geben.

Und ich denke, das wird gemacht, damit man sagen kann, dass 702 in dieser Phase auf 703 wartet, und alle, die danach kommen, haben keinen Eintrag in diesem Feld. Aber sobald der erste Wartende geht und alle, die zu diesem Zeitpunkt bis zur Aktualisierung gewartet haben, den gleichen Marker erhalten. Und deshalb glaube ich, dass dies gemacht wurde, damit wir der Reihe nach verarbeiten können, damit sie richtig geordnet sind.

Ich habe es immer als ein ziemlich seltsames Phänomen betrachtet. Denn hier zum Beispiel listen wir sie überhaupt nicht auf. Aber ich denke, jedes Mal, wenn wir eine neue Sperre vergeben, schauen wir auf all jene, die im Wartemodus sind. Dann stellen wir alle in eine Schlange. Und jeder neue, der kommt, kommt nur in die Schlange, wenn die nächste Person mit der Verarbeitung fertig ist. Eine sehr gute Frage. Vielen Dank für die Frage!

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

Das Problem ist folgendes. Technisch gesehen können Sie entweder diesen oder jenen wecken. Deshalb wecken wir den einen oder den anderen. Aber was passiert im Betriebssystem? Sie sehen, wie 703 ganz oben seine eigene Transaktions-ID blockiert hat. So funktioniert Postgres. Und 703 wird durch seine eigene Transaktions-ID blockiert, deshalb, wenn jemand warten möchte, wird er auf 703 warten. Im Wesentlichen beendet 703 die Operation. Und erst nach seinem Abschluss wird einer der Prozesse geweckt. Und wir wissen nicht, welcher Prozess das sein wird. Dann verarbeiten wir schrittweise alles. Aber es ist unklar, welcher Prozess zuerst geweckt wird, denn es kann einer dieser Prozesse sein. Im Wesentlichen hatten wir einen Scheduler, der sagte, dass wir jetzt jeden dieser Prozesse wecken können. Wir wählen einfach einen zufällig aus. Daher müssen beide markiert werden, da wir jeden von ihnen wecken können.

Und das Problem ist, dass wir CP-Unendlichkeit haben. Daher könnten wir durchaus einen späteren Prozess wecken. Wenn wir beispielsweise einen späteren Prozess wecken, erwarten wir denjenigen, der gerade die Sperre erhalten hat, daher bestimmen wir nicht, welcher Prozess zuerst geweckt wird. Wir schaffen einfach eine solche Situation, und das System wird sie in zufälliger Reihenfolge wecken.

Ja Artikel über Locks von Jegor Rogow. Schauen Sie, sie sind auch interessant und nützlich. Das Thema ist natürlich äußerst komplex. Vielen Dank, Bruce!

Quelle: habr.com

60GB SSD 8Gb DDR4