{"id":81089,"date":"2020-05-11T01:42:24","date_gmt":"2020-05-10T23:42:24","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov"},"modified":"2020-05-11T01:42:24","modified_gmt":"2020-05-10T23:42:24","slug":"tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","title":{"rendered":"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot;<\/strong><\/p>\n<p><\/p>\n<p>In diesem Bericht werde ich die Hauptfehler in Anwendungen behandelt, die in der Phase des Designs und der Codierung auftreten. Ich werde nur die Fehler betrachten, die zu Bloat in PostgreSQL f\u00fchren. In der Regel ist dies der Anfang vom Ende der Leistung Ihres Systems insgesamt, obwohl anfangs keine Anzeichen daf\u00fcr sichtbar waren.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/a9e199bfe2e01c76966b32868790f8f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Ich freue mich, alle willkommen zu hei\u00dfen! Dieser Bericht ist nicht so technisch wie der vorherige von meinem Kollegen. Er richtet sich haupts\u00e4chlich an Entwickler von Backend-Systemen, da wir eine betr\u00e4chtliche Anzahl von Kunden haben. Alle machen die gleichen Fehler. Ich werde Ihnen dar\u00fcber berichten und erkl\u00e4ren, zu welchen fatalen und negativen Konsequenzen diese Fehler f\u00fchren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/c6c84dbafc595ae3068cd8bf804ccee7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Warum werden Fehler begangen? Es gibt zwei Gr\u00fcnde: aus einer gewissen Risikobereitschaft, vielleicht klappt es ja, und aus Unkenntnis \u00fcber bestimmte Mechanismen, die auf der Ebene zwischen der Datenbank und der Anwendung sowie in der Datenbank selbst stattfinden. <\/p>\n<p><\/p>\n<p>Ich werde Ihnen drei Beispiele mit schrecklichen Bildern zeigen, wie alles schiefgelaufen ist. Kurz werde ich den Mechanismus erl\u00e4utern, der dort wirkt. Au\u00dferdem werde ich erkl\u00e4ren, wie man damit umgeht, wenn sie auftreten, und welche pr\u00e4ventiven Methoden zur Vermeidung von Fehlern eingesetzt werden k\u00f6nnen. Ich werde von Hilfsmitteln berichten und n\u00fctzliche Links bereitstellen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/b0230d992f5b44f0e542df2e4b4d526f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich verwendete eine Testdatenbank, in der ich zwei Tabellen hatte. Eine Tabelle mit Kundendaten und die andere mit den Operationen auf diesen Konten. In bestimmten Abst\u00e4nden aktualisieren wir die Best\u00e4nde auf diesen Konten.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/1d2a21278b095b07546e1bb870819dbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Die Quell Daten der Tabelle: Sie ist recht klein, 2 MB. Die Antwortzeit f\u00fcr die Datenbank und insbesondere f\u00fcr die Tabelle ist ebenfalls sehr gut. Und eine ziemlich hohe Belastung \u2013 2.000 Operationen pro Sekunde auf der Tabelle.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/dea5a4b1ac7952f8cfed0e2e1cfc10dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Durch diesen Vortrag werde ich Ihnen Grafiken zeigen, um anschaulich darzustellen, was passiert. Es wird immer zwei Folien mit Grafiken geben. Die erste Folie zeigt, was insgesamt auf dem Server passiert. <\/p>\n<p><\/p>\n<p>In dieser Situation sehen wir, dass unsere Tabelle in der Tat eine kleine Gr\u00f6\u00dfe hat. Der Index hat eine geringe Gr\u00f6\u00dfe von 2 MB. Das ist das erste Diagramm von links. <\/p>\n<p><\/p>\n<p>Die durchschnittliche Serverantwortzeit ist ebenfalls stabil und gering. Dies ist das Diagramm oben rechts. <\/p>\n<p><\/p>\n<p>Das Diagramm unten links zeigt die l\u00e4ngsten Transaktionen. Wir sehen, dass die Transaktionen schnell abgeschlossen werden. Der Autovacuum funktioniert hier noch nicht, da es sich um einen Teststart handelte. In Zukunft wird er aktiviert und n\u00fctzlich sein.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/9e9b46acd9a878ff70ca4a7850adff09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Die zweite Folie ist immer der testenden Tabelle gewidmet. In diesem Fall aktualisieren wir st\u00e4ndig die Best\u00e4nde auf den Konten des Kunden. Wir sehen, dass die durchschnittliche Antwortzeit f\u00fcr die Aktualisierungsoperation ausreichend gut ist, unter einer Millisekunde. Auch die CPU-Ressourcen (oberes rechtes Diagramm) werden gleichm\u00e4\u00dfig und in einem angemessenen Ma\u00df verbraucht. <\/p>\n<p><\/p>\n<p>Das untere rechte Diagramm zeigt, wie viel operativen und Speicherspeicher wir durchgehen, um die ben\u00f6tigte Zeile vor dem Aktualisieren zu finden. Die Anzahl der Transaktionen pro Tabelle betr\u00e4gt 2.000 pro Sekunde, wie ich urspr\u00fcnglich sagte. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/84760d52716209b8dcfffb462c67a8e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und nun geschieht eine Trag\u00f6die. Aus irgendeinem Grund tritt eine lange vergessene Transaktion auf. Die Gr\u00fcnde sind meist banal: <\/p>\n<p><\/p>\n<ul>\n<li>Eine der h\u00e4ufigsten Situationen ist, dass wir im Code der Anwendung begonnen haben, auf einen externen Dienst zuzugreifen. Und dieser Dienst antwortet uns nicht. Das bedeutet, dass wir eine Transaktion ge\u00f6ffnet, eine \u00c4nderung in der Datenbank vorgenommen haben und dann aus der Anwendung heraus E-Mails gelesen oder einen anderen Dienst in unserer Infrastruktur genutzt haben, und aus irgendeinem Grund erhalten wir keine Antwort. Und unsere Sitzung bleibt in einem Zustand h\u00e4ngen \u2013 ungewiss, wann sie gel\u00f6st wird.<\/li>\n<li>Die zweite Situation ist, wenn in unserem Code aus irgendeinem Grund eine Ausnahme aufgetreten ist. Und wir haben im Ausnahmefall das Schlie\u00dfen der Transaktion nicht verarbeitet. Das f\u00fchrt dazu, dass wir eine schwebende Sitzung mit einer offenen Transaktion haben. <\/li>\n<li>Und zuletzt \u2013 das ist auch ein ziemlich h\u00e4ufiges Szenario. Das ist minderwertiger Code. Einige Frameworks \u00f6ffnen eine Transaktion. Sie bleibt offen, und Sie wissen m\u00f6glicherweise nicht in der Anwendung, dass sie offen ist. <\/li>\n<\/ul>\n<p><\/p>\n<p>Worauf f\u00fchren solche Dinge hin? <\/p>\n<p><\/p>\n<p>Wir sehen, dass unsere Tabellen und Indizes stark anwachsen. Das ist genau der Effekt des Bloat. F\u00fcr die Datenbank bedeutet das, dass die Antwortzeiten sprunghaft ansteigen und die Last auf dem Datenbankserver zunimmt. Letztendlich leidet die Anwendung darunter. Wenn Sie im Code 10 Millisekunden f\u00fcr die Datenbankabfrage und weitere 10 Millisekunden f\u00fcr Ihre Logik ben\u00f6tigt haben, betrug die Gesamtzeit 20 Millisekunden. Jetzt wird die Situation jedoch ganz anders aussehen. <\/p>\n<p><\/p>\n<p>Schauen wir uns an, was passiert. Das Diagramm unten links zeigt, dass wir eine lange, langandauernde Transaktion haben. Und wenn wir uns das obere linke Diagramm ansehen, sehen wir, dass die Gr\u00f6\u00dfe der Tabelle von zwei Megabyte pl\u00f6tzlich auf 300 Megabyte angestiegen ist. Dabei hat sich die Datenmenge in der Tabelle nicht ge\u00e4ndert, d. h. dort bleibt eine erhebliche Menge an M\u00fcll zur\u00fcck.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/b1947f6487e440a770a1251a955e62d2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Die allgemeine Situation in Bezug auf die durchschnittliche Antwortzeit des Servers hat sich ebenfalls um mehrere Gr\u00f6\u00dfenordnungen verschlechtert. Das bedeutet, dass alle Anfragen an den Server erheblich zur\u00fcckgehen. Gleichzeitig laufen interne Postgres-Prozesse wie der Autovakuum, die versuchen, etwas zu tun und Ressourcen verbrauchen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/8e91f035d1dd04e72e842d714cc611a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Was ist mit unserem Diagramm los? Genau das gleiche. Die durchschnittliche Antwortzeit unseres Diagramms ist sprunghaft angestiegen. Konkreter zu den verbrauchten Ressourcen sehen wir, dass die CPU-Auslastung stark gestiegen ist. Das ist das obere rechte Diagramm. Und das ist geschehen, weil die CPU eine Menge nutzloser Zeilen durchgehen muss, um eine sinnvolle zu finden. Das ist das untere rechte Diagramm. Das Ergebnis: Die Anzahl der Anfragen pro Sekunde hat stark abgenommen, weil die Datenbank nicht in der Lage ist, die gleiche Anzahl von Anfragen zu verarbeiten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/424685ce852bc5f3ef77151f8d3d7289.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir m\u00fcssen zur\u00fcck ins Leben. Wir gehen ins Internet und erfahren, dass lange Transaktionen zu einem Problem f\u00fchren. Wir finden und beenden diese Transaktion und alles wird wieder normal. Alles funktioniert wie gew\u00fcnscht. <\/p>\n<p><\/p>\n<p>Wir haben uns beruhigt, aber nach einiger Zeit bemerken wir, dass die Anwendung nicht mehr so funktioniert wie vor der Notfallsituation. Die Anfragen werden dennoch langsamer bearbeitet, und zwar erheblich langsamer. In meinem Beispiel ist es anderthalb bis zwei Mal langsamer. Die Serverlast ist ebenfalls h\u00f6her als vor dem Vorfall. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3037719a31f8d18fc42745716c4da5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Die Frage stellt sich: \u201eWas passiert mit der Datenbank in diesem Moment?\u201c. Mit der Datenbank liegt folgende Situation vor. Im Transaktionsdiagramm sehen Sie, dass sie angehalten hat und es tats\u00e4chlich keine langwierigen Transaktionen gibt. Aber die Gr\u00f6\u00dfe der Tabelle ist w\u00e4hrend des Ausfalls fatal angestiegen und hat sich seitdem nicht reduziert. Die durchschnittliche Zeit in der Datenbank hat sich stabilisiert. Die Antworten scheinen in einem angemessenen Tempo zu erfolgen, das f\u00fcr uns akzeptabel ist. Der Autovakuum ist aktiver geworden und hat begonnen, mit der Tabelle zu arbeiten, da er mehr Daten verarbeiten muss. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/f6205242c4024dc3ed4cade5844dbf76.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Konkret zu der getesteten Tabelle mit den Konten, in der wir die Restbest\u00e4nde \u00e4ndern: Die Antwortzeit f\u00fcr die Abfrage scheint wieder normal zu sein. Tats\u00e4chlich liegt sie jedoch anderthalbmal h\u00f6her.<\/p>\n<p><\/p>\n<p>Und hinsichtlich der CPU-Belastung sehen wir, dass die Belastung nicht wieder auf das erforderliche Niveau zur\u00fcckgekehrt ist, das vor dem Ausfall vorhanden war. Die Gr\u00fcnde daf\u00fcr sind im Diagramm unten rechts zu finden. Es ist zu erkennen, dass dort ein \u00fcberm\u00e4\u00dfiger Speicherverbrauch stattfindet. Das hei\u00dft, um die ben\u00f6tigte Zeile zu finden, verschwenden wir Serverressourcen der Datenbank, um nutzlose Daten zu durchforsten. Die Anzahl der Transaktionen pro Sekunde hat sich stabilisiert. <\/p>\n<p><\/p>\n<p>Im Gro\u00dfen und Ganzen ist es gut, aber die Situation ist schlechter als zuvor. Eine offensichtliche Degeneration der Datenbank als Folge unserer Anwendung, die mit dieser Datenbank arbeitet. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/0dfc9cd453fd84bc639ffd99cf189fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Um zu verstehen, was dort passiert, wenn Sie bei der letzten Pr\u00e4sentation nicht anwesend waren, gibt es jetzt ein wenig Theorie. Theorie \u00fcber den internen Prozess. Was ist die Autovacuum-Funktion und was macht sie?<\/p>\n<p><\/p>\n<p>Kurz gefasst zum Verst\u00e4ndnis. Zu einem bestimmten Zeitpunkt haben wir eine Tabelle. In der Tabelle befinden sich Zeilen. Diese Zeilen k\u00f6nnen aktiv, lebendig und f\u00fcr uns jetzt notwendig sein. In der Abbildung sind sie gr\u00fcn markiert. Und es gibt auch Tote Zeilen, die bereits verarbeitet wurden, aktualisiert wurden und neue Eintr\u00e4ge erhalten haben. Diese sind markiert, weil sie f\u00fcr die Datenbank nicht mehr von Interesse sind. Sie liegen jedoch in der Tabelle aufgrund der Besonderheit von Postgres.<\/p>\n<p><\/p>\n<p>Warum ist der Autovacuum notwendig? Der Autovacuum kommt irgendwann, greift auf die Datenbank zu und fragt: \u201eGib mir bitte die ID der \u00e4ltesten Transaktion, die derzeit in der Datenbank ge\u00f6ffnet ist\u201c. Die Datenbank gibt diese ID zur\u00fcck. Basierend darauf durchk\u00e4mmt der Autovacuum die Zeilen in der Tabelle. Wenn er sieht, dass einige Zeilen durch wesentlich \u00e4ltere Transaktionen ge\u00e4ndert wurden, hat er das Recht, diese als wiederverwendbar zu markieren, indem er dort neue Daten speichert. Das ist ein Hintergrundprozess.<\/p>\n<p><\/p>\n<p>In der Zwischenzeit arbeiten wir weiter mit der Datenbank und nehmen \u00c4nderungen an der Tabelle vor. Und auf diese wiederverwendbaren Zeilen schreiben wir neue Daten. So entsteht ein Kreislauf, d. h. es entstehen immer wieder einige tote alte Zeilen, die durch neue Zeilen ersetzt werden, die wir brauchen. Und das ist ein normales Zustand f\u00fcr PostgreSQL.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/98dd4451a7ca5f418775f72822c2840c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Was ist w\u00e4hrend des Vorfalls passiert? Wie ist dieser Prozess abgelaufen?<\/p>\n<p><\/p>\n<p>Wir hatten eine Tabelle in einem bestimmten Zustand, einige Zeilen waren aktiv, andere inaktiv. Dann kam der Auto-Vakuum. Er fragte die Datenbank nach der \u00e4ltesten Transaktion, der damit verbundenen ID. Diese ID konnte mehrere Stunden oder nur zehn Minuten alt sein. Es h\u00e4ngt davon ab, wie hoch die Last in Ihrer Datenbank ist. Und dann begann er, nach Zeilen zu suchen, die er als wiederverwendbar kennzeichnen kann. Er fand jedoch keine solchen Zeilen in unserer Tabelle. <\/p>\n<p><\/p>\n<p>W\u00e4hrenddessen arbeiten wir weiterhin an der Tabelle. Wir f\u00fchren Updates durch und \u00e4ndern Daten. Was kann die Datenbank in dieser Zeit tun? Sie bleibt nichts anderes \u00fcbrig, als neue Zeilen am Ende der bestehenden Tabelle hinzuzuf\u00fcgen. Dadurch beginnt die Gr\u00f6\u00dfe der Tabelle zu wachsen. <\/p>\n<p><\/p>\n<p>F\u00fcr unsere Arbeit ben\u00f6tigen wir tats\u00e4chlich die aktiven Zeilen. Aber w\u00e4hrend eines solchen Problems haben wir einen sehr niedrigen Prozentsatz aktiver Zeilen im gesamten Volumen der Tabelle. <\/p>\n<p><\/p>\n<p>Wenn wir eine Anfrage durchf\u00fchren, muss die Datenbank durch alle Zeilen, sowohl die roten als auch die gr\u00fcnen, durchsuchen, um die ben\u00f6tigte Zeile zu finden. Der Effekt der Aufbl\u00e4hung der Tabelle mit nutzlosen Daten wird als \u201ebloat\u201c bezeichnet, der zudem unseren Speicherplatz frisst. Erinnern Sie sich, es waren 2 MB, jetzt sind es 300 MB? Und ersetzen Sie Megabyte durch Gigabyte, und Sie werden so schnell all Ihre Speicherressourcen los sein.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/fe7cb6b5c99610744ebcfe5ad7235d1e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Welche Konsequenzen kann das f\u00fcr uns haben? <\/p>\n<p><\/p>\n<ul>\n<li>In meinem Beispiel sind die Tabelle und der Index um das 150-fache gewachsen. Einige unserer Kunden hatten noch gravierendere F\u00e4lle, in denen der Speicherplatz auf der Festplatte knapp wurde. <\/li>\n<li>Die Gr\u00f6\u00dfe von Tabellen wird nie von selbst kleiner. Der Autovacuum kann in einigen F\u00e4llen das Ende der Tabelle abtrennen, wenn dort nur tote Zeilen vorhanden sind. Da jedoch eine st\u00e4ndige Rotation stattfindet, kann eine gr\u00fcne Zeile am Ende h\u00e4ngen bleiben und nicht aktualisiert werden, w\u00e4hrend alle anderen zu Beginn der Tabelle aufgezeichnet werden. Aber das ist so unwahrscheinlich, dass Sie nicht darauf hoffen sollten, dass Ihre Tabelle von selbst kleiner wird. <\/li>\n<li>Die Datenbank muss sich durch einen Haufen nutzloser Zeilen w\u00fchlen. Das kostet Speicherressourcen, CPU-Leistung und Energie. <\/li>\n<li>Und das hat unmittelbare Auswirkungen auf unsere Anwendung, denn w\u00e4hrend wir anfangs 10 Millisekunden f\u00fcr eine Anfrage und weitere 10 Millisekunden f\u00fcr unseren Code ben\u00f6tigten, ben\u00f6tigten wir w\u00e4hrend des Ausfalls eine Sekunde f\u00fcr die Anfrage und 10 Millisekunden f\u00fcr den Code. Das bedeutet, dass die Leistung der Anwendung erheblich gesunken ist. Nachdem wir den Ausfall behoben hatten, ben\u00f6tigten wir 20 Millisekunden f\u00fcr die Anfrage und 10 Millisekunden f\u00fcr den Code. Das hei\u00dft, dass wir immer noch eine Leistungsverschlechterung von anderthalb Mal haben. Und das alles wegen einer Transaktion, die h\u00e4ngen geblieben ist, m\u00f6glicherweise aufgrund unseres eigenen Verschuldens. <\/li>\n<li>Und die Frage ist: \u201eWie bekommen wir alles wieder zur\u00fcck?\u201c, damit alles wieder gut wird und die Anfragen so schnell laufen wie vor dem Ausfall. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/1bf46e8cd9b28ca2862f978f2ca85819.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Es gibt daf\u00fcr einen bestimmten Arbeitszyklus, der durchgef\u00fchrt wird. <\/p>\n<p><\/p>\n<p>Zun\u00e4chst m\u00fcssen wir die Problem tabellen finden, die aufgebl\u00e4ht sind. Wir verstehen, dass f\u00fcr bestimmte Tabellen die Datens\u00e4tze aktiver sind, f\u00fcr andere weniger aktiv. Und daf\u00fcr wird ein Erweiterungstool verwendet. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>. Mit dieser Erweiterung k\u00f6nnen Sie Abfragen erstellen, die Ihnen helfen, Tabellen zu finden, die stark anwachsen. <\/p>\n<p><\/p>\n<p>Nachdem Sie diese Tabellen gefunden haben, m\u00fcssen sie komprimiert werden. Daf\u00fcr gibt es bereits Werkzeuge. In unserem Unternehmen verwenden wir drei Werkzeuge. Das erste ist das integrierte VACUUM FULL. Es ist hart, streng und kompromisslos, aber manchmal sehr n\u00fctzlich. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Pg_repack<\/a><\/noindex> und <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex> \u2013 das sind externe Dienstprogramme zur Komprimierung von Tabellen. Sie sind schonender zu der Datenbank. <\/p>\n<p><\/p>\n<p>Sie werden je nach Ihren Vorlieben eingesetzt. Aber ich werde am Ende mehr dar\u00fcber erz\u00e4hlen. Wichtig ist, dass es drei Werkzeuge gibt. Man hat die Auswahl. <\/p>\n<p><\/p>\n<p>Nachdem wir alles behoben und sichergestellt haben, dass alles gut ist, sollten wir wissen, wie wir diese Situation in Zukunft vermeiden k\u00f6nnen:<\/p>\n<p><\/p>\n<ul>\n<li>Sie kann ziemlich leicht vermieden werden. Man muss die Dauer der Sitzungen auf dem Master-Server im Auge behalten. <strong>Besonders gef\u00e4hrlich sind Sitzungen im Zustand idle in transaction.<\/strong>Das sind die, die eine Transaktion er\u00f6ffnet haben, etwas gemacht haben und dann weg sind oder einfach h\u00e4ngen geblieben sind, sich im Code verloren haben. <\/li>\n<li>Und f\u00fcr Sie als Entwickler ist es wichtig, den Code in dem Moment zu testen, in dem diese Situationen auftreten. Es ist nicht schwer zu bewerkstelligen. Es wird eine n\u00fctzliche Kontrolle sein. Sie werden eine gro\u00dfe Anzahl an \"Kinderproblemen\" im Zusammenhang mit langen Transaktionen vermeiden. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/d55465d96c4018db733954867d23aaba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Auf diesen Grafiken wollte ich Ihnen zeigen, wie sich die Tabelle und das Verhalten der Datenbank ge\u00e4ndert haben, nachdem ich in diesem Fall ein VACUUM FULL auf die Tabelle angewendet habe. Das ist nicht in der Produktion.<\/p>\n<p><\/p>\n<p>Die Tabellengr\u00f6\u00dfe ist sofort wieder in einen normalen Arbeitszustand von ein paar Megabyte zur\u00fcckgekehrt. Das hat die durchschnittliche Antwortzeit des Servers nicht wesentlich beeinflusst. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/cbb07ad24dba899395223d1ca25e438e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aber spezifisch zu unserem Testtisch, wo wir die Best\u00e4nde auf den Konten aktualisiert haben, sehen wir, dass die durchschnittliche Antwortzeit f\u00fcr die Anfrage zur Aktualisierung der Daten in der Tabelle auf einen unkritischen Wert gesenkt wurde. Auch die vom Prozessor beanspruchten Ressourcen f\u00fcr die Ausf\u00fchrung dieser Anfrage sind auf ein unkritisches Niveau gefallen. Und das Diagramm in der rechten unteren Ecke zeigt, dass wir jetzt genau die Zeile finden, die wir brauchen, ohne durch die Menge der inaktiven Zeilen zu gehen, die vor der Verdichtung der Tabelle vorhanden waren. Die durchschnittliche Anfragezeit blieb ungef\u00e4hr auf dem gleichen Niveau. Aber hier habe ich eher eine Ungenauigkeit meiner Hardware.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/c1d90c5442e02fce209dc40e048a8ca2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier endet die erste Geschichte. Sie ist die h\u00e4ufigste und passiert jedem, unabh\u00e4ngig von der Erfahrung des Kunden und der Qualifikation der Programmierer. Fr\u00fcher oder sp\u00e4ter geschieht es. <\/p>\n<p><\/p>\n<p>Die zweite Geschichte, in der wir die Last verteilen und die Serverressourcen optimieren.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/cda421c554d1329107ddc935045cc1b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Wir sind gewachsen und haben uns zu ernsthaften Spielern entwickelt. Wir verstehen, dass wir eine Replikate haben und es gut w\u00e4re, die Last auszugleichen: Schreiben auf dem Master und Lesen von der Replikate. Diese Situation tritt normalerweise auf, wenn wir Berichte oder ETL erstellen m\u00f6chten. Das Unternehmen ist dar\u00fcber sehr erfreut. Es m\u00f6chte verschiedene Berichte mit komplexer Analyse. <\/li>\n<li>Die Berichte sind zeitaufwendig, da komplexe Analysen nicht in Millisekunden berechnet werden k\u00f6nnen. Wir, als f\u00e4hige Leute, schreiben den Code. Wir machen in der Anwendung Einf\u00fcgungen, dass wir die Aufzeichnungen auf dem Master f\u00fchren und die Berichte auf der Replikate ausf\u00fchren. <\/li>\n<li>Wir verteilen die Last. <\/li>\n<li>Alles funktioniert hervorragend. Wir sind gro\u00dfartig. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/e94c8c492197a5015ac8aae79389a4c2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wie sieht diese Situation aus? Konkret habe ich auf diesen Grafiken die Dauer der Transaktionen mit der Dauer der Transaktionen von der Replikate hinzugef\u00fcgt. Alle anderen Grafiken beziehen sich nur auf den Master-Server. <\/p>\n<p><\/p>\n<p>Die Tabelle mit den Berichten ist inzwischen gewachsen. Es gibt mehr davon. Wir sehen, dass die durchschnittliche Serverantwortzeit stabil ist. Wir sehen, dass wir auf der Replikate eine lang laufende Transaktion haben, die 2 Stunden dauert. Wir beobachten die ruhige Arbeit des Autovacuum, das tote Zeilen verarbeitet. Und es geht uns gut. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/2da8acf098d12d6f146ab9b9dcb54b81.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Insbesondere bei der getesteten Tabelle aktualisieren wir weiterhin die Best\u00e4nde auf den Konten. Auch haben wir eine stabile Antwortzeit auf Anfragen sowie einen stabilen Ressourcenverbrauch. Bei uns l\u00e4uft alles gut. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/3621ef723017bac6fb635caf0a5f4de6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Es l\u00e4uft alles gut, bis diese Berichte aufgrund von Konflikten mit der Replikation herausgeschossen werden. Und sie werden mit konstanter Regelm\u00e4\u00dfigkeit herausgeschossen. <\/p>\n<p><\/p>\n<p>Wir gehen ins Internet und beginnen zu lesen, warum das passiert. Und finden eine L\u00f6sung. <\/p>\n<p><\/p>\n<p>Die erste L\u00f6sung besteht darin, die Replikationsverz\u00f6gerung zu erh\u00f6hen. Wir wissen, dass unser Bericht 3 Stunden dauert. Wir setzen die Replikationsverz\u00f6gerung auf 3 Stunden. Wir starten alles, aber trotzdem haben wir weiterhin Probleme, dass Berichte manchmal herausgeschossen werden. <\/p>\n<p><\/p>\n<p>Wir wollen, dass alles perfekt ist. Also suchen wir weiter. Und finden im Internet eine coole Einstellung \u2013 hot_standby_feedback. Wir aktivieren es. Hot_standby_feedback erm\u00f6glicht es uns, die Arbeit des Autovacuum auf dem Master zur\u00fcckzuhalten. Damit beseitigen wir v\u00f6llig die Replikationskonflikte. Und bei uns funktioniert alles gut mit den Berichten.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3c315168bdd3f392d2e8a1c5861004.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Was passiert in dieser Zeit mit unserem Master-Server? Mit dem Master-Server haben wir ein ernsthaftes Problem. Momentan beobachten wir die Grafiken, nachdem ich beide Einstellungen aktiviert habe. Und wir sehen, dass die Sitzung auf der Replica auf irgendeine Weise die Situation auf dem Master-Server beeinflusst. Es hat tats\u00e4chlich Auswirkungen, da es den Autovacuum-Prozess unterbrochen hat, der die toten Zeilen bereinigt. Die Gr\u00f6\u00dfe der Tabelle ist wieder in die H\u00f6he geschossen. Die durchschnittliche Ausf\u00fchrungszeit der Abfragen in der gesamten Datenbank ist ebenfalls stark gestiegen. Die Autovacuum-Prozesse sind wieder ein wenig angespannt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/980611dcce8b189dc50f422ffd3d2d72.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Insbesondere bei unserer Tabelle sehen wir, dass die Aktualisierung der Daten ebenfalls extrem gestiegen ist. Der Ressourcenverbrauch der CPU hat sich ebenfalls stark erh\u00f6ht. Wir durchlaufen wieder eine gro\u00dfe Anzahl toter, nutzloser Zeilen. Und die Antwortzeit f\u00fcr diese Tabelle sowie die Anzahl der Transaktionen sind gesunken. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/a648fd313a5dccf45f0056dc13c54263.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wie wird das aussehen, wenn wir nicht wissen, wor\u00fcber ich zuvor gesprochen habe?<\/p>\n<p><\/p>\n<ul>\n<li>Wir beginnen mit der Fehlersuche. Wenn wir in der ersten Phase auf Probleme gesto\u00dfen sind, wissen wir, dass dies auf eine lange Transaktion zur\u00fcckzuf\u00fchren sein kann, und wir schauen uns den Master an. Das Problem liegt auf unserem Master. Er ist \u00fcberlastet. Er wird hei\u00df, und die Last ist fast auf Hundert. <\/li>\n<li>Die Anfragen dort sind langsam, aber wir sehen keine langen Transaktionen. Wir verstehen nicht, woran es liegt. Wir wissen nicht, wo wir suchen sollen. <\/li>\n<li>Wir pr\u00fcfen die Serverhardware. Vielleicht ist unser RAID ausgefallen. Vielleicht ist ein RAM-Riegel kaputt. Es k\u00f6nnte alles M\u00f6gliche sein. Aber nein, die Server sind neu, alles funktioniert einwandfrei. <\/li>\n<li>Alle sind in Bewegung: Administratoren, Entwickler und der Direktor. Nichts hilft. <\/li>\n<li>Und irgendwann beginnt sich alles pl\u00f6tzlich von selbst zu verbessern. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/7d4f6417bc5cb3cec33679d843c6661d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In der Zwischenzeit wurde auf der Replik der Auftrag erfolgreich ausgef\u00fchrt und gesendet. Wir haben einen Bericht erhalten. Das Gesch\u00e4ft ist weiterhin zufrieden. Wie wir sehen, ist unsere Tabelle wieder gewachsen und wird nicht kleiner. In dem Diagramm mit den Sitzungen habe ich einen Ausschnitt dieser langen Transaktion von der Replikation gelassen, damit Sie den Verlauf der Stabilisierung besser absch\u00e4tzen k\u00f6nnen. <\/p>\n<p><\/p>\n<p>Die Sitzung ist abgelaufen. Und nur nach einiger Zeit kommt der Server einigerma\u00dfen wieder in Ordnung. Und die durchschnittliche Antwortzeit f\u00fcr Anfragen auf dem Master-Server normalisiert sich. Das liegt daran, dass der Autovacuum endlich die M\u00f6glichkeit erhalten hat, diese toten Zeilen zu bereinigen und zu kennzeichnen. Und er hat begonnen, seine Arbeit zu machen. Und so schnell, wie er das tut, werden wir in den Normalzustand zur\u00fcckkehren.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/547d195e08de1566da818150a47218eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>An der getesteten Tabelle, in der wir die Best\u00e4nde der Konten aktualisieren, sehen wir genau das gleiche Bild. Die durchschnittliche Aktualisierungszeit des Kontos normalisiert sich ebenfalls allm\u00e4hlich. Die vom Prozessor verbrauchten Ressourcen verringern sich ebenfalls. Und die Anzahl der Transaktionen pro Sekunde kehrt zur Normalit\u00e4t zur\u00fcck. Aber wieder nicht in den Zustand, wie wir ihn vor dem Ausfall hatten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/29372a5e9124690931485a7aea65befc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben in jedem Fall einen R\u00fcckgang der Leistung wie im ersten Fall um das eineinhalb- bis zweifache, manchmal sogar mehr. <\/p>\n<p><\/p>\n<p>Wir haben vermeintlich alles richtig gemacht. Die Last verteilt. Die Hardware steht nicht still. Wir haben die Anfragen vern\u00fcnftig aufgeteilt, aber trotzdem ist alles schlecht gelaufen. <\/p>\n<p><\/p>\n<ul>\n<li>Hot_standby_feedback nicht aktivieren? Ja, es wird nicht empfohlen, es ohne triftigen Grund zu aktivieren. Denn diese Einstellung hat direkten Einfluss auf den Master-Server und stoppt dort die Funktionsweise des Autovakuums. Wenn Sie es auf einer Replikation aktivieren und vergessen, kann es den Master-Server gef\u00e4hrden und zu gro\u00dfen Problemen mit der Anwendung f\u00fchren. <\/li>\n<li>Die max_standby_streaming_delay erh\u00f6hen? Ja, das ist f\u00fcr Berichte sinnvoll. Wenn Sie einen dreist\u00fcndigen Bericht haben und m\u00f6chten, dass er nicht aufgrund von Replikationskonflikten fehlschl\u00e4gt, erh\u00f6hen Sie einfach die Verz\u00f6gerung. Ein lang laufender Bericht ben\u00f6tigt nie die Daten, die gerade jetzt in die Datenbank kommen. Wenn er dreist\u00fcndig ist, bedeutet das, dass Sie ihn f\u00fcr einen \u00e4lteren Zeitraum ansto\u00dfen. Ob Sie drei oder sechs Stunden Verz\u00f6gerung haben, spielt keine Rolle; aber Sie k\u00f6nnen stabil Berichte erhalten, ohne Probleme mit deren Abbruch zu haben. <\/li>\n<li>Nat\u00fcrlich m\u00fcssen wir lange Sitzungen auf den Replikaten \u00fcberwachen, insbesondere wenn Sie sich entschieden haben, hot_standby_feedback auf dem Replikat zu aktivieren. Denn es kann alles M\u00f6gliche passieren. Wir haben dieses Replikat einem Entwickler gegeben, damit er Anfragen testen kann. Er hat eine verr\u00fcckte Anfrage geschrieben, sie gestartet und ging dann Tee trinken, w\u00e4hrend wir einen Master erhalten haben. Oder wir haben nicht die richtige Anwendung dort ausgef\u00fchrt. Die Situationen sind vielf\u00e4ltig. Sitzungen auf den Replikaten m\u00fcssen genauso sorgf\u00e4ltig \u00fcberwacht werden wie auf dem Master. <\/li>\n<li>Und wenn Sie schnelle und langwierige Anfragen an die Replikate haben, ist es in diesem Fall besser, sie zur Lastenverteilung aufzuteilen. Hier ist der Link zu streaming_delay. F\u00fcr schnelle Anfragen sollten Sie eine Replik mit einer geringen Replikationsverz\u00f6gerung haben. F\u00fcr langwierige Berichtsanfragen k\u00f6nnen Sie eine Replik haben, die bis zu 6 Stunden oder einen Tag hinterherhinkt. Das ist eine v\u00f6llig normale Situation. <\/li>\n<\/ul>\n<p><\/p>\n<p>Wir beheben die Konsequenzen auf die gleiche Weise:<\/p>\n<p><\/p>\n<ul>\n<li>Wir finden aufgebl\u00e4hte Tabellen.<\/li>\n<li>Und komprimieren sie mit dem geeignetsten Werkzeug, das uns passt. <\/li>\n<\/ul>\n<p><\/p>\n<p>Die zweite Geschichte endete hier. Wir machen mit der dritten Geschichte weiter. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/c8784e0be27883640cb8f6919a1c25e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Das ist ebenfalls ziemlich gew\u00f6hnlich f\u00fcr uns, in der wir eine Migration durchf\u00fchren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/a04b9cd88a0e7e8a3b960ef930eb2657.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Jedes Softwareprodukt entwickelt sich weiter. Die Anforderungen \u00e4ndern sich. Wir m\u00f6chten uns in jedem Fall weiterentwickeln. Und manchmal ist es notwendig, die Daten in der Tabelle zu aktualisieren, insbesondere um ein Update im Rahmen unserer Migration f\u00fcr die neuen Funktionen, die wir im Rahmen unserer Weiterentwicklung einf\u00fchren, durchzuf\u00fchren. <\/li>\n<li>Das alte Datenformat entspricht nicht mehr unseren Bed\u00fcrfnissen. Nehmen wir an, wir schauen uns die zweite Tabelle an, in der meine Transaktionen zu diesen Konten aufgef\u00fchrt sind. Angenommen, sie waren in Rubel, und wir haben beschlossen, die Genauigkeit zu erh\u00f6hen und in Kopeken zu arbeiten. Daf\u00fcr m\u00fcssen wir ein Update durchf\u00fchren: das Feld mit dem Transaktionsbetrag mal hundert multiplizieren. <\/li>\n<li>In der modernen Welt verwenden wir automatisierte Tools zur Versionskontrolle von Datenbanken. Angenommen, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a><\/noindex>wir schreiben unsere Migration hinein. Testen sie auf unserer Testdatenbank. Alles l\u00e4uft hervorragend. Das Update wird durchgef\u00fchrt. Es blockiert die Arbeit f\u00fcr eine gewisse Zeit, aber wir erhalten aktualisierte Daten. Und wir k\u00f6nnen neue Funktionen darauf basieren. Alles wurde getestet, \u00fcberpr\u00fcft und genehmigt. <\/li>\n<li>Wir haben planm\u00e4\u00dfige Arbeiten durchgef\u00fchrt und die Migration abgeschlossen. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/9e046583f7b1723fc1eaf61a03900918.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier sehen Sie die Migration mit dem Update. Da es sich bei mir um Kontenoperationen handelt, hatte die Tabelle eine Gr\u00f6\u00dfe von 15 GB. Und da wir jede Zeile aktualisieren, haben wir die Tabelle mit dem Update verdoppelt, weil wir jede Zeile neu geschrieben haben. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/06120c98ea43d0568045e71935c23592.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W\u00e4hrend der Migration konnten wir nichts mit dieser Tabelle machen, da alle Anfragen in der Warteschlange standen und darauf warteten, dass dieses Update abgeschlossen wird. Aber ich m\u00f6chte Ihre Aufmerksamkeit auf die Zahlen auf der vertikalen Achse lenken. Das hei\u00dft, wir haben eine durchschnittliche Anfragezeit vor der Migration von etwa 5 Millisekunden und die CPU-Belastung, die Anzahl der Blockoperationen zum Lesen des Disk-Speichers, ist geringer als 7,5. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/69a3ba4d1d0cec7d39284e09e9d3055b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben die Migration durchgef\u00fchrt und hatten wieder Probleme. <\/p>\n<p><\/p>\n<p>Die Migration war erfolgreich, aber:<\/p>\n<p><\/p>\n<ul>\n<li>Die alte Funktionalit\u00e4t ben\u00f6tigt nun mehr Zeit. <\/li>\n<li>Die Tabelle ist wieder gewachsen. <\/li>\n<li>Die Serverlast ist wieder h\u00f6her als zuvor. <\/li>\n<li>Und nat\u00fcrlich besch\u00e4ftigen wir uns immer noch mit der Funktionalit\u00e4t, die gut lief, und haben sie etwas verbessert. <\/li>\n<\/ul>\n<p><\/p>\n<p>Und das ist wieder Bloat, der uns erneut das Leben schwer macht. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/becd7cce3a1c8821c81c96257f41202b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier zeige ich, dass die Tabelle, wie in den vorherigen zwei F\u00e4llen, nicht zu ihren fr\u00fcheren Gr\u00f6\u00dfen zur\u00fcckkehren wird. Die durchschnittliche Serverlast scheint angemessen zu sein. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/4d703a60d43a3460bc3782d49865b690.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wenn wir jedoch auf die Tabelle mit den Abfragen schauen, sehen wir, dass die durchschnittliche Abfragezeit sich verdoppelt hat. Die CPU-Auslastung und die Anzahl der abgerufenen Zeilen im Speicher sind auf \u00fcber 7,5 gestiegen, zuvor lag sie darunter. Bei den Prozessoren hat sich die Last verdoppelt, bei blockbasierten Operationen um das 1,5-fache, was bedeutet, dass wir eine Leistungseinbu\u00dfe des Servers erhalten haben. Und als Folge davon \u2013 eine Leistungseinbu\u00dfe unserer Anwendung. Die Anzahl der Aufrufe blieb dabei ungef\u00e4hr auf dem gleichen Niveau. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/80772afa0643b29f5314a2482c9dfe0d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier ist es wichtig zu verstehen, wie man solche Migrationen richtig durchf\u00fchrt. Und das muss gemacht werden. Wir f\u00fchren diese Migrationen ziemlich regelm\u00e4\u00dfig durch.<\/p>\n<p><\/p>\n<ul>\n<li>Solch gro\u00dfe Migrationen werden nicht automatisch durchgef\u00fchrt. Sie m\u00fcssen immer kontrolliert werden. <\/li>\n<li>Es ist notwendig, dass eine sachkundige Person die Kontrolle hat. Wenn Sie einen DBA im Team haben, sollte der das \u00fcbernehmen. Das ist seine Aufgabe. Wenn nicht, sollte die erfahrenste Person die Migration durchf\u00fchren, die wei\u00df, wie man mit Datenbanken arbeitet. <\/li>\n<li>Das neue Datenbankschema sorgt daf\u00fcr, dass wir auch dann, wenn wir eine Spalte aktualisieren, immer schrittweise arbeiten, also im Voraus, bevor die neue Version der Anwendung ver\u00f6ffentlicht wird.<\/li>\n<li>Es werden neue Felder hinzugef\u00fcgt, in die wir die aktualisierten Daten schreiben werden. <\/li>\n<li>Wir transferieren die Daten aus dem alten Feld in das neue Feld in kleinen Mengen. Warum machen wir das? Erstens kontrollieren wir diesen Prozess st\u00e4ndig. Wir wissen, dass wir bereits eine bestimmte Anzahl von Chargen \u00fcbertragen haben und noch eine bestimmte Anzahl \u00fcbrig ist. <\/li>\n<li>Ein weiterer positiver Aspekt ist, dass wir zwischen jeder Charge eine Transaktion abschlie\u00dfen und eine neue \u00f6ffnen, was dem Auto-Vakuum erlaubt, die Tabelle zu verarbeiten und tote Zeilen zur Wiederverwendung zu kennzeichnen. <\/li>\n<li>F\u00fcr die Zeilen, die w\u00e4hrend des Betriebs der Anwendung erscheinen (da unsere alte Anwendung noch aktiv ist), f\u00fcgen wir einen Trigger hinzu, der neue Werte in die neuen Felder schreibt. In unserem Fall ist das das alte Value multipliziert mit hundert. <\/li>\n<li>Wenn wir absolut hartn\u00e4ckig sind und dasselbe Feld wollen, benennen wir einfach nach Abschluss aller Migrationen und vor dem Rollout der neuen Version der Anwendung die Felder um. Die alten in irgendeinen einfallenden Namen und die neuen Felder benennen wir in die alten um. <\/li>\n<li>Und erst nach diesem Schritt starten wir die neue Version der Anwendung. <\/li>\n<\/ul>\n<p><\/p>\n<p>Und dabei erhalten wir keinen Bloat und verlieren nicht an Leistung. <\/p>\n<p><\/p>\n<p>So endet die dritte Geschichte. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/2afab2906b5ccd30e4c8772248818057.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Jetzt etwas ausf\u00fchrlicher zu den Werkzeugen, die ich in der ersten Geschichte erw\u00e4hnt habe. <\/p>\n<p><\/p>\n<p>Bevor Sie nach Bloat suchen, sollten Sie unbedingt die Erweiterung installieren. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Um Ihnen das Erstellen der Abfragen zu ersparen, haben wir in unserer Arbeit diese Abfragen bereits erstellt. Sie k\u00f6nnen sie verwenden. Hier sind zwei Abfragen dargestellt. <\/p>\n<p><\/p>\n<ul>\n<li>Die erste Abfrage l\u00e4uft zwar l\u00e4nger, aber sie zeigt Ihnen die genauen Werte des Bloat in der Tabelle. <\/li>\n<li>Die zweite Abfrage l\u00e4uft schneller und ist sehr effektiv, wenn es darum geht, schnell zu beurteilen, ob es Bloat in der Tabelle gibt oder nicht. Sie m\u00fcssen auch verstehen, dass Bloat in der Postgres-Tabelle immer vorhanden ist. Das ist eine Eigenheit seines MVCC-Modells. <\/li>\n<li>Und 20 % Bloat sind in den meisten F\u00e4llen f\u00fcr Tabellen normal. Das hei\u00dft, Sie m\u00fcssen sich keine Sorgen machen und diese Tabelle nicht komprimieren. <\/li>\n<\/ul>\n<p><\/p>\n<p>Wie man Tabellen erkennt, die bei uns aufgebl\u00e4ht sind, haben wir verstanden, insbesondere wann sie mit nutzlosen Daten aufgebl\u00e4ht wurden. <\/p>\n<p><\/p>\n<p>Nun, wie man Bloat behebt:<\/p>\n<p><\/p>\n<ul>\n<li>Wenn wir eine kleine Tabelle und gute Festplatten haben, d. h. bei einer Tabelle bis zu einem Gigabyte, kann man gut VACUUM FULL verwenden. Es wird f\u00fcr einige Sekunden eine exklusive Sperre auf die Tabelle erfordern und gut ist, daf\u00fcr erledigt es alles schnell und gr\u00fcndlich. Was macht VACUUM FULL? Es nimmt eine exklusive Sperre auf die Tabelle und schreibt die lebenden Zeilen aus alten Tabellen in die neue Tabelle. Und am Ende tauscht es sie aus. Die alten Dateien werden gel\u00f6scht und die neuen ersetzen die alten. Aber w\u00e4hrend seiner Arbeit nimmt es eine exklusive Sperre auf die Tabelle. Das bedeutet, dass Sie mit dieser Tabelle nichts tun k\u00f6nnen: Sie k\u00f6nnen nicht in sie schreiben, nicht in sie lesen und sie nicht modifizieren. VACUUM FULL ben\u00f6tigt au\u00dferdem zus\u00e4tzlichen Speicherplatz auf der Festplatte, um die Daten zu speichern.<\/li>\n<li>Das n\u00e4chste Werkzeug <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">pg_repack<\/a><\/noindex>. Es funktioniert im Prinzip \u00e4hnlich wie VACUUM FULL, da es ebenfalls Daten aus alten Dateien in neue schreibt und sie in der Tabelle ersetzt. Allerdings wird dabei nicht von Anfang an ein exklusives Lock auf die Tabelle gesetzt, sondern nur zu dem Zeitpunkt, wenn die neuen Daten bereit sind, um die Dateien zu ersetzen. Die Anforderungen an den Speicherplatz sind die gleichen wie bei VACUUM FULL. Sie ben\u00f6tigen zus\u00e4tzlichen Speicherplatz, was kritisch werden kann, wenn Sie Terabyte gro\u00dfe Tabellen haben. Au\u00dferdem ist er ziemlich ressourcenintensiv, da er aktiv mit Ein- und Ausgabeoperationen arbeitet. <\/li>\n<li>Das dritte Dienstprogramm ist <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex>. Es geht sparsamer mit den Ressourcen um, da es nach etwas anderen Prinzipien arbeitet. Der Hauptzweck von pgcompacttable besteht darin, dass es die aktiven Zeilen in der Tabelle nach vorne verschiebt. Anschlie\u00dfend f\u00fchrt es ein VACUUM auf dieser Tabelle durch, da wir wissen, dass am Anfang die aktiven und am Ende die inaktiven Zeilen stehen. Das VACUUM schneidet dann den unn\u00f6tigen Rest ab, was bedeutet, dass es nicht viel zus\u00e4tzlichen Speicherplatz ben\u00f6tigt. Zudem kann es hinsichtlich der Ressourcen noch weiter optimiert werden. <\/li>\n<\/ul>\n<p><\/p>\n<p>Das sind die Werkzeuge. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrey Salkov\" src=\"\/wp-content\/uploads\/2020\/05\/4187915e54e54a0b85a342fe0280f78f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wenn Ihnen das Thema Bloat interessant erscheint und Sie tiefer eintauchen m\u00f6chten, hier sind einige n\u00fctzliche Links:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres\">https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres<\/a><\/noindex> \u2013 das ist ein Vortrag meines Kollegen. Er gibt einen \u00dcberblick dar\u00fcber, wo der Speicherplatz in Postgres w\u00e4hrend seiner Arbeit und Lebensdauer hingeht. Und es gibt einen sehr gro\u00dfen und detaillierten technischen Teil f\u00fcr Datenbankadministratoren \u00fcber Bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\">https:\/\/github.com\/dataegret\/pg-utils<\/a><\/noindex> \u2013 das ist der Link zu unserem Repository, wo wir viele n\u00fctzliche Skripte zur \u00dcberpr\u00fcfung des Datenbankstatus aufbewahren. Dort finden Sie Skripte zur Suche nach Bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Dritte<\/a><\/noindex> und <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">vierten<\/a><\/noindex> Links zu Werkzeugen, die Ihnen helfen, Tabellen zu komprimieren. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html\">http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html<\/a><\/noindex> \u2013 das ist ein Beitrag meines Kollegen. Darin wird Bloat auf einem niveauvollen und detaillierten technischen Level behandelt, das besonders f\u00fcr Administratoren relevant ist. <\/li>\n<\/ul>\n<p><\/p>\n<p>Ich habe versucht, den Entwicklern ein Schreckensszenario darzustellen, da sie unsere direkten Kunden der Datenbanken sind und verstehen m\u00fcssen, welche Auswirkungen ihre Handlungen haben. Ich hoffe, mir ist das gelungen. Vielen Dank f\u00fcr Ihre Aufmerksamkeit!<\/p>\n<p><\/p>\n<p>Fragen<\/p>\n<p><\/p>\n<p><em>Vielen Dank f\u00fcr den Vortrag! Sie sprachen dar\u00fcber, wie Probleme identifiziert werden k\u00f6nnen. Aber wie kann man sie vorhersehen? Ich hatte eine Situation, in der die Anfragen nicht nur deshalb h\u00e4ngen blieben, weil sie auf bestimmte externe Dienste zugriffen. Es waren einfach einige komplizierte Joins. Es gab einige harmlose, winzige Anfragen, die \u00fcber einen Tag hinweg h\u00e4ngen blieben und dann anfingen, merkw\u00fcrdige Dinge zu tun. Das klingt sehr nach dem, was Sie beschreiben. Wie kann man das verfolgen? Soll ich st\u00e4ndig kontrollieren, welche Anfrage h\u00e4ngt? Wie kann man das verhindern?<\/em><\/p>\n<p><\/p>\n<p>In diesem Fall ist es die Aufgabe der Administratoren Ihres Unternehmens, nicht unbedingt der DBA.<\/p>\n<p><\/p>\n<p><em>Ich bin Administrator.<\/em><\/p>\n<p><\/p>\n<p>In PostgreSQL gibt es eine Ansicht namens pg_stat_activity, die die h\u00e4ngenden Abfragen anzeigt. Dort k\u00f6nnen Sie sehen, wie lange sie dort h\u00e4ngen.<\/p>\n<p><\/p>\n<p><em>Muss ich alle 5 Minuten nachsehen?<\/em><\/p>\n<p><\/p>\n<p>Richten Sie einen Cron-Job ein und \u00fcberpr\u00fcfen Sie es regelm\u00e4\u00dfig. Wenn Sie eine lang laufende Anfrage haben, senden Sie eine E-Mail und das war's. Sie m\u00fcssen nicht st\u00e4ndig nachsehen; das kann automatisiert werden. Sie erhalten eine E-Mail, auf die Sie reagieren k\u00f6nnen. Alternativ k\u00f6nnen Sie auch automatische Benachrichtigungen einrichten.<\/p>\n<p><\/p>\n<p><em>Gibt es klare Gr\u00fcnde, warum das passiert?<\/em><\/p>\n<p><\/p>\n<p>Ich habe einige aufgelistet. Es gibt auch kompliziertere Beispiele. Und das Gespr\u00e4ch k\u00f6nnte lange dauern.<\/p>\n<p><\/p>\n<p><em>Danke f\u00fcr den Vortrag! Ich wollte noch etwas zur pg_repack-Nutzung kl\u00e4ren. Wenn es keine exklusive Sperre macht, dann\u2026<\/em><\/p>\n<p><\/p>\n<p>Es macht eine exklusive Sperre. <\/p>\n<p><\/p>\n<p>\u2026 <em>k\u00f6nnte ich potenziell Daten verlieren. Mein Programm sollte in dieser Zeit nichts schreiben?<\/em><\/p>\n<p><\/p>\n<p>Nein, es arbeitet ruhig mit der Tabelle, d. h. pg_repack \u00fcbertr\u00e4gt zuerst alle aktiven Zeilen. Nat\u00fcrlich gibt es dabei einige Schreibvorg\u00e4nge in der Tabelle. Es f\u00fcgt einfach diesen kleinen Rest hinzu. <\/p>\n<p><\/p>\n<p><em>Das hei\u00dft, er macht es am Ende tats\u00e4chlich?<\/em><\/p>\n<p><\/p>\n<p>Am Ende nimmt er die exklusive Sperre, um diese Dateien zu tauschen. <\/p>\n<p><\/p>\n<p><em>Wird das schneller sein als VACUUM FULL?<\/em><\/p>\n<p><\/p>\n<p>VACUUM FULL, sobald es gestartet wurde, nimmt sofort eine exklusive Sperre. Und solange es nicht alles erledigt hat, gibt es sie nicht frei. pg_repack nimmt eine exklusive Sperre nur w\u00e4hrend des Austausches der Dateien. In diesem Moment k\u00f6nnen Sie dort nicht schreiben, aber die Daten gehen nicht verloren, alles wird in Ordnung sein. <\/p>\n<p><\/p>\n<p><em>Hallo! Sie haben von der Funktionsweise des Autovacuum gesprochen. Dort gab es ein Diagramm mit roten, gelben und gr\u00fcnen Zellen. Das hei\u00dft, die gelben wurden als gel\u00f6scht markiert. Kann man in diese alten Zellen etwas Neues eintragen?<\/em><\/p>\n<p><\/p>\n<p>Ja. Postgres l\u00f6scht die Zeilen nicht. Das ist eine Besonderheit von ihm. Wenn wir eine Zeile aktualisieren, wird die alte als gel\u00f6scht markiert. Dort wird die ID der Transaktion, die diese Zeile ge\u00e4ndert hat, eingetragen und eine neue Zeile wird geschrieben. Und wir haben Sessions, die potenziell darauf zugreifen k\u00f6nnen. Irgendwann werden sie ganz alt. Der Autovacuum l\u00e4uft \u00fcber diese Zeilen und markiert sie als nicht mehr ben\u00f6tigt. In diese k\u00f6nnen dann neue Daten zur\u00fcckgeschrieben werden. <\/p>\n<p><\/p>\n<p><em>Ich verstehe. Aber die Frage zielt etwas anders ab. Ich habe noch nicht abgeschlossen. Angenommen, wir haben eine Tabelle. Darin gibt es Felder variabler Gr\u00f6\u00dfe. Und wenn ich versuche, etwas Neues einzuf\u00fcgen, passt es m\u00f6glicherweise einfach nicht in die alte Zelle.<\/em> <\/p>\n<p><\/p>\n<p>Nein, in jedem Fall wird die gesamte Zeile aktualisiert. In Postgres gibt es zwei Modelle zur Speicherung von Daten. Er w\u00e4hlt basierend auf dem Datentyp. Es gibt Daten, die direkt in der Tabelle gespeichert werden, und es gibt auch tos-Daten. Das sind gro\u00dfe Datenmengen: Text, JSON. Diese werden in separaten Tabellen gespeichert. Und dasselbe Problem mit Bloat tritt auch bei diesen Tabellen auf, d. h. alles bleibt gleich. Sie sind nur separat ausgelagert. <\/p>\n<p><\/p>\n<p><em>Vielen Dank f\u00fcr den Vortrag! Wie akzeptabel ist es, um die Dauer von Anfragen den Statement Timeout zu verwenden?<\/em><\/p>\n<p><\/p>\n<p>Sehr akzeptabel. Wir verwenden das \u00fcberall. Da wir keine eigenen Dienste haben und Fernsupport leisten, haben wir ziemlich unterschiedliche Kunden. Alle sind damit vollkommen zufrieden. Das hei\u00dft, wir haben Aufgaben in cron, die dies \u00fcberpr\u00fcfen. Mit dem Kunden wird einfach die Dauer der Sitzungen besprochen, bevor wir sie beenden. Das kann eine Minute sein, das kann 10 Minuten sein. Das h\u00e4ngt von der Last auf der Datenbank und ihrem Ziel ab. Aber bei allen nutzen wir pg_stat_activity.<\/p>\n<p><\/p>\n<p><em>Vielen Dank f\u00fcr die Pr\u00e4sentation! Ich versuche, Ihre Pr\u00e4sentation auf meine Anwendungen anzuwenden. Und anscheinend starten wir \u00fcberall die Transaktion, beenden sie \u00fcberall ausdr\u00fccklich. Wenn eine Ausnahme auftritt, findet trotzdem ein Rollback statt. Und da habe ich nachgedacht. Denn die Transaktion kann m\u00f6glicherweise nicht ausdr\u00fccklich starten. Das ist vermutlich ein Hinweis f\u00fcr die Dame. Wenn ich einfach einen Datensatz aktualisiere, wird in PostgreSQL die Transaktion gestartet und sie wird erst beendet, wenn die Verbindung unterbrochen wird?<\/em><\/p>\n<p><\/p>\n<p>Wenn Sie jetzt vom Anwendungstransaktionsniveau sprechen, h\u00e4ngt das von dem Treiber ab, den Sie verwenden, von dem ORM, das eingesetzt wird. Es gibt dort sehr viele Einstellungen. Wenn bei Ihnen auto commit aktiviert ist, wird die Transaktion gestartet und sofort geschlossen.<\/p>\n<p><\/p>\n<p><em>D. h. wird sie sofort nach dem Update geschlossen?<\/em><\/p>\n<p><\/p>\n<p>Das h\u00e4ngt von den Einstellungen ab. Eine Einstellung habe ich genannt: auto commit. Sie ist ziemlich verbreitet. Wenn sie aktiv ist, wird die Transaktion gestartet und sofort geschlossen. Wenn Sie nicht ausdr\u00fccklich \u00abstart transaction\u00bb und \u00abend transaction\u00bb gesagt haben, sondern einfach eine Abfrage in der Sitzung gestartet haben. <\/p>\n<p><\/p>\n<p><em>Hallo! Danke f\u00fcr den Bericht! Stellen wir uns vor, wir haben eine Datenbank, die immer gr\u00f6\u00dfer wird und auf dem Server geht der Speicher aus. Gibt es irgendwelche Werkzeuge, um diese Situation zu beheben?<\/em> <\/p>\n<p><\/p>\n<p>Den Speicherplatz auf dem Server sollte man regelm\u00e4\u00dfig \u00fcberwachen. <\/p>\n<p><\/p>\n<p><em>Zum Beispiel, der DBA ist gerade beim Tee trinken, war im Urlaub usw.<\/em><\/p>\n<p><\/p>\n<p>Wenn ein Dateisystem erstellt wird, dann wird dort zumindest ein gewisser Freiraum reserviert, wo keine Daten geschrieben werden. <\/p>\n<p><\/p>\n<p><em>Was ist, wenn der Speicher ganz voll ist?<\/em><\/p>\n<p><\/p>\n<p>Das nennt sich reservierter Speicher, das hei\u00dft, man kann ihn freimachen und je nach Gr\u00f6\u00dfe, die ihm zugewiesen wurde, erh\u00e4lt man freien Platz. Standardm\u00e4\u00dfig wei\u00df ich nicht, wie viel da ist. Ansonsten muss man Festplatten hinzuf\u00fcgen, damit man Speicherplatz f\u00fcr die Wiederherstellungsoperation hat. Man kann eine Tabelle l\u00f6schen, die garantiert nicht ben\u00f6tigt wird. <\/p>\n<p><\/p>\n<p><em>Gibt es keine anderen Werkzeuge?<\/em><\/p>\n<p><\/p>\n<p>Das ist immer Handarbeit. Und je nach Platz wird entschieden, was dort am besten gemacht werden kann, denn es gibt kritische und nicht kritische Daten. Und f\u00fcr jede Datenbank und Anwendung, die damit arbeitet, h\u00e4ngt es vom Gesch\u00e4ft ab. Man entscheidet immer je nach Platz. <\/p>\n<p><\/p>\n<p><em>Vielen Dank f\u00fcr den Vortrag! Ich habe zwei Fragen. Erstens, Sie haben Folien pr\u00e4sentiert, auf denen gezeigt wird, dass bei h\u00e4ngenden Transaktionen sowohl der Umfang des Tabellenraums als auch die Gr\u00f6\u00dfe des Indexes ansteigt. Danach gab es viele Tools, die die Tabelle verpacken. Was ist mit dem Index?<\/em><\/p>\n<p><\/p>\n<p>Die verpacken sie auch. <\/p>\n<p><\/p>\n<p><em>Aber der Vakuum betrifft den Index nicht?<\/em><\/p>\n<p><\/p>\n<p>Einige arbeiten mit dem Index. Zum Beispiel pg_rapack, pgcompacttable. VACUUM rekonstruiert die Indizes, wirkt sich auf sie aus. Bei VACUUM FULL geht es darum, alles neu zu schreiben, d.h. es wirkt auf alle. <\/p>\n<p><\/p>\n<p><em>Und die zweite Frage. Ich habe nicht verstanden, warum die Berichte auf Replikaten so stark von der Replikation selbst abh\u00e4ngen. Ich dachte, Berichte sind Lesevorg\u00e4nge und Replikation ist ein Schreibvorgang.<\/em> <\/p>\n<p><\/p>\n<p>Worin besteht der Konflikt bei der Replikation? Wir haben einen Master, auf dem Prozesse laufen. Dort findet ein Autovacuum statt. Was macht das Autovacuum? Es entfernt alte Zeilen. Wenn zu diesem Zeitpunkt ein Abfrage auf der Replik l\u00e4uft, die diese alten Zeilen liest, und der Master festgestellt hat, dass das Autovacuum diese Zeilen als potenziell \u00fcberschreibbar markiert hat, dann werden wir sie \u00fcberschreiben. Und es kam ein Datenpaket, als wir die Zeilen \u00fcberschreiben sollten, die f\u00fcr die Abfrage auf der Replik erforderlich sind; der Replikationsprozess wartet dann auf das Timeout, das Sie eingestellt haben. Danach wird PostgreSQL entscheiden, was f\u00fcr ihn wichtiger ist. Und die Replikation ist ihm wichtiger als die Abfrage, also wird er die Abfrage zur\u00fcckweisen, um diese \u00c4nderungen auf der Replik auszuf\u00fchren. <\/p>\n<p><\/p>\n<p><em>Andrey, ich habe eine Frage. Sind diese wunderbaren Diagramme, die Sie w\u00e4hrend der Pr\u00e4sentation gezeigt haben, das Ergebnis Ihrer Arbeit mit einem Ihrer Tools? Was wurde verwendet, um die Diagramme zu erstellen?<\/em><\/p>\n<p><\/p>\n<p>Es ist ein Dienst. <noindex><a rel=\"nofollow\" href=\"https:\/\/okmeter.io\/\">Okmeter<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><em>Ist es ein kommerzielles Produkt?<\/em><\/p>\n<p><\/p>\n<p>Ja. Es ist ein kommerzielles Produkt.<\/p>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/501040\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u0432\u043e\u0437\u044c\u043c\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 Postgresql. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":81090,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-81089","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u0432\u043e\u0437\u044c\u043c\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 Postgresql. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u0432\u043e\u0437\u044c\u043c\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 Postgresql. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren. Andrej Salkin | ProHoster","description":"Ich lade Sie ein, die Zusammenfassung des Berichts von Andrej Salkin vom Anfang des Jahres 2016 zu lesen: \"Typische Fehler in Anwendungen, die zu Bloat in PostgreSQL f\u00fchren.\" In diesem Bericht werde ich die Hauptfehler in Anwendungen behandeln, die in der Entwurfs- und Programmierphase auftreten. Ich werde mich nur mit den Fehlern befassen, die zu Bloat in PostgreSQL f\u00fchren. In der Regel ist dies der Beginn des Endes der Leistung.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u0432\u043e\u0437\u044c\u043c\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 Postgresql. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-10T23:42:24+00:00","article:modified_time":"2020-05-10T23:42:24+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"81089","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:05:22","updated":"2022-09-27 16:01:50"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/81089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=81089"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/81089\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/81090"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=81089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=81089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=81089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}