{"id":90103,"date":"2020-07-29T13:42:32","date_gmt":"2020-07-29T11:42:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij"},"modified":"2020-07-29T13:42:32","modified_gmt":"2020-07-29T11:42:32","slug":"patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij","title":{"rendered":"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/6404cba13214f499d1f347cca0aacbe7.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Das Hauptziel von Patroni ist es, High Availability f\u00fcr PostgreSQL zu gew\u00e4hrleisten. Aber Patroni ist nur eine Vorlage und kein fertiges Werkzeug (was in der Dokumentation auch gesagt wird). Auf den ersten Blick, wenn man Patroni in einer Testumgebung konfiguriert, sieht man, wie gro\u00dfartig dieses Werkzeug ist und wie einfach es unsere Versuche verarbeitet, den Cluster zum Absturz zu bringen. In der Praxis jedoch l\u00e4uft in einer Produktionsumgebung nicht immer alles so sch\u00f6n und elegant wie in der Testumgebung.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ff445e6d76a2ad46a232b705e104446f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich erz\u00e4hle ein wenig \u00fcber mich. Ich habe als Systemadministrator angefangen. Habe in der Webentwicklung gearbeitet. Seit 2014 arbeite ich bei Data Egret. Das Unternehmen besch\u00e4ftigt sich mit Beratung im Bereich Postgres. Und wir betreuen ausschlie\u00dflich Postgres und arbeiten jeden Tag mit Postgres, daher haben wir verschiedene Expertisen in Bezug auf den Betrieb. <\/p>\n<p><\/p>\n<p>Ende 2018 haben wir langsam angefangen, Patroni zu nutzen. Und wir haben eine bestimmte Erfahrung gesammelt. Wir haben es diagnostiziert, optimiert und sind zu unseren Best Practices gekommen. In diesem Vortrag werde ich dar\u00fcber berichten.<\/p>\n<p><\/p>\n<p>Neben Postgres liebe ich Linux. Ich mag es, mich damit zu besch\u00e4ftigen und zu forschen, ich liebe es, Kerne zu kompilieren. Ich interessiere mich f\u00fcr Virtualisierung, Container, Docker, Kubernetes. Das alles interessiert mich, weil alte Admin-Gewohnheiten zum Tragen kommen. Ich besch\u00e4ftige mich gerne mit \u00dcberwachungssystemen. Und ich liebe postgres-bezogene Aspekte des Administrierens, wie z.B. Replikation, Datensicherung. In meiner Freizeit programmiere ich in Go. Ich bin kein Software-Ingenieur, ich programmiere nur f\u00fcr mich selbst in Go. Und ich finde das sehr angenehm. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/02cfd9293af5a8410c91e39afe2c75e6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Ich denke, viele von Ihnen wissen, dass es in Postgres kein HA (High Availability) \u201eaus der Box\u201c gibt. Um HA zu erhalten, muss man etwas installieren, konfigurieren, M\u00fche aufwenden und es verwirklichen. <\/li>\n<li>Es gibt mehrere Werkzeuge, und Patroni ist eines davon, das HA ziemlich gut und sehr effektiv l\u00f6st. Aber wenn man das alles in einer Testumgebung installiert und startet, k\u00f6nnen wir sehen, dass alles funktioniert, wir k\u00f6nnen Probleme reproduzieren und beobachten, wie Patroni damit umgeht. Und wir werden sehen, dass alles wunderbar l\u00e4uft. <\/li>\n<li>In der Praxis haben wir jedoch mit verschiedenen Problemen zu k\u00e4mpfen gehabt. \u00dcber diese Probleme werde ich berichten.<\/li>\n<li>Ich werde erz\u00e4hlen, wie wir das diagnostiziert haben und welche Anpassungen wir vorgenommen haben \u2013 ob uns das geholfen hat oder nicht. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/7126b45b40dd08521e80a3c150382bec.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Ich werde nicht erz\u00e4hlen, wie man Patroni installiert, weil man das im Internet google kann, man kann sich die Konfigurationsdateien anschauen, um zu verstehen, wie alles startet und eingestellt wird. Man kann sich in die Schemas und Architekturen einarbeiten, indem man Informationen dar\u00fcber im Internet findet. <\/li>\n<li>Ich werde nicht \u00fcber die Erfahrungen anderer sprechen. Ich werde nur \u00fcber die Probleme berichten, mit denen wir konfrontiert waren. <\/li>\n<li>Ich werde auch nicht \u00fcber Probleme sprechen, die au\u00dferhalb von Patroni und PostgreSQL liegen. Zum Beispiel werde ich nicht \u00fcber Probleme mit der Lastverteilung berichten, als unser Cluster zusammenbrach. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/3f8d179e7c78ce83e8842ef5c72fe30d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und eine kleine Disclaimer, bevor wir mit unserem Vortrag beginnen. <\/p>\n<p><\/p>\n<p>All diese Probleme, mit denen wir konfrontiert waren, traten in den ersten 6-7-8 Monaten des Betriebs auf. Im Laufe der Zeit haben wir zu unseren eigenen internen Best Practices gefunden. Und die Probleme sind verschwunden. Daher wurde der Vortrag vor etwa einem halben Jahr angek\u00fcndigt, als dies alles frisch im Ged\u00e4chtnis war und ich mich gut daran erinnerte. <\/p>\n<p><\/p>\n<p>Im Laufe der Vorbereitung des Vortrags habe ich bereits alte Postmortems durchgesehen und Protokolle betrachtet. Und einige Details k\u00f6nnten vergessen worden sein, oder einige Details k\u00f6nnten w\u00e4hrend der Problemanalyse nicht gr\u00fcndlich genug untersucht worden sein, weshalb es in manchen Punkten so erscheinen k\u00f6nnte, dass die Probleme nicht vollst\u00e4ndig behandelt wurden oder es an Informationen mangelt. Daher bitte ich um Entschuldigung f\u00fcr diesen Punkt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/30d414284a41fcbc3bf417c9da28ca52.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Was ist Patroni?<\/p>\n<p><\/p>\n<ul>\n<li>Es ist ein Muster f\u00fcr den Aufbau von HA. So steht es in der Dokumentation. Und aus meiner Sicht ist das eine sehr richtige Pr\u00e4zisierung. Patroni ist keine silberne Kugel, die all Ihre Probleme l\u00f6sen wird; man muss also Anstrengungen unternehmen, damit es funktioniert und Nutzen bringt. <\/li>\n<li>Es handelt sich um einen Agentendienst, der auf jedem Dienst mit einer Datenbank installiert wird und der gewisserma\u00dfen ein Init-System f\u00fcr Ihr Postgres ist. Er startet Postgres, stoppt es, setzt es neu in Gang, \u00e4ndert Konfigurationen und ver\u00e4ndert die Topologie Ihres Clusters. <\/li>\n<li>Um den Zustand des Clusters und dessen aktuelle Darstellung zu speichern, braucht man ein entsprechendes Speichersystem. In dieser Hinsicht hat Patroni den Weg eingeschlagen, den Zustand in einem externen System zu speichern. Es handelt sich um ein System zur verteilten Speicherung von Konfigurationen. Das k\u00f6nnen Etcd, Consul, ZooKeeper oder das Kubernetes-Etcd sein, also irgendeine dieser Optionen. <\/li>\n<li>Eine der Besonderheiten von Patroni ist, dass Sie den Auto-Failover direkt out-of-the-box erhalten, indem Sie ihn einfach konfigurieren. Im Vergleich zu Repmgr gibt es dort den Failover als Teil des Pakets. Mit Repmgr erhalten wir den Switchover, aber wenn wir den Auto-Failover wollen, muss er zus\u00e4tzlich konfiguriert werden. Im Patroni ist der Auto-Failover bereits enthalten.<\/li>\n<li>Es gibt noch viele andere Dinge. Zum Beispiel die Verwaltung von Konfigurationen, das Hinzuf\u00fcgen neuer Replikate, Datensicherung usw. Aber das sind Themen, die \u00fcber den Bericht hinausgehen, dar\u00fcber werde ich nicht sprechen. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fed0f1ce931df99ca76ae1116f8098cc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ein kleines Fazit ist, dass die Hauptaufgabe von Patroni darin besteht, den Auto-Failover gut und zuverl\u00e4ssig zu gestalten, damit unser Cluster funktionsf\u00e4hig bleibt und die Anwendung \u00c4nderungen in der Cluster-Topologie nicht wahrnimmt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fac52620957efa47ced330e7cc8084e0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wenn wir jedoch beginnen, Patroni zu verwenden, wird unser System etwas komplexer. Wenn wir vorher Postgres hatten, erhalten wir mit der Verwendung von Patroni Patroni selbst, wir erhalten DCS, wo der Status gespeichert wird. Und das alles muss irgendwie funktionieren. Was kann also schiefgehen?<\/p>\n<p><\/p>\n<p>Es kann Folgendes schiefgehen:<\/p>\n<p><\/p>\n<ul>\n<li>Postgres kann ausfallen. Es kann sich um den Master oder die Replik handeln, eines von beiden kann ausfallen. <\/li>\n<li>Patroni selbst kann ausfallen. <\/li>\n<li>DCS, in dem der Status gespeichert wird, kann ausfallen.<\/li>\n<li>Und das Netzwerk kann ausfallen. <\/li>\n<\/ul>\n<p><\/p>\n<p>All diese Punkte werde ich im Bericht behandeln. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/1aeaf46d37bf1935b514b0581e0dbd0b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich werde die F\u00e4lle der Komplexit\u00e4t nach behandeln, nicht aus der Sicht der Komponenten, die betroffen sind, sondern aus der Sicht der subjektiven Wahrnehmung, wonach ein Fall f\u00fcr mich schwierig war, weil er schwer zu analysieren war\u2026 und umgekehrt, dass ein anderer Fall einfach war und leicht zu analysieren war. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/65b0c98bf2284610e955ced5eb998f39.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und der erste Fall ist der einfachste. Das ist der Fall, wenn wir einen Datenbankcluster genommen haben und auf demselben Cluster unser DCS-Speicher eingerichtet haben. Das ist der h\u00e4ufigste Fehler. Es ist ein Fehler im Design der Architektur, d. h. die Kombination verschiedener Komponenten an einem Ort. <\/p>\n<p><\/p>\n<p>So, es gab einen Failover, lassen Sie uns herausfinden, was passiert ist. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/244b69d623fe2205c2d9ed2aa4620067.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier interessiert uns der Zeitpunkt, an dem der Failover stattgefunden hat. Das hei\u00dft, uns interessiert dieser Moment, als sich der Status des Clusters \u00e4ndert. <\/p>\n<p><\/p>\n<p>Aber ein Failover ist nicht immer ein einmaliges Ereignis, d. h. es braucht nicht immer eine bestimmte Zeitspanne, es kann sich hinziehen. Es kann \u00fcber einen l\u00e4ngeren Zeitraum andauern.<\/p>\n<p><\/p>\n<p>Deshalb hat er eine Start- und eine Endzeit, d. h. es handelt sich um ein fortlaufendes Ereignis. Wir teilen alle Ereignisse in drei Intervalle auf: Wir haben die Zeit vor dem Failover, w\u00e4hrend des Failovers und nach dem Failover. Das hei\u00dft, wir betrachten alle Ereignisse in diesem Zeitrahmen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a0ed61afe55d1a157147e0d80b17e5d1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und als erstes, als das Failover auftrat, suchen wir die Ursache, was passiert ist, was dazu f\u00fchrte, dass das Failover stattfand. <\/p>\n<p><\/p>\n<p>Wenn wir uns die Protokolle ansehen, werden wir die klassischen Protokolle von Patroni sehen. Er teilt uns mit, dass der Server zum Master geworden ist und die Rolle des Masters auf diesen Knoten \u00fcbergegangen ist. Hier ist es hervorgehoben. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/9998c69f7d0d4358b277f4e0e7b4350f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Als n\u00e4chstes m\u00fcssen wir verstehen, warum das Failover passiert ist, d. h. welche Ereignisse dazu gef\u00fchrt haben, dass die Rolle des Masters von einem Knoten zu einem anderen gewechselt hat. Und in diesem Fall ist alles einfach. Wir haben einen Kommunikationsfehler mit dem Speichersystem. Der Master stellte fest, dass er nicht mit dem DCS arbeiten kann, d. h. es gab ein Problem mit der Interaktion. Und er sagt, dass er nicht mehr der Master sein kann und legt seine Befugnisse nieder. Diese Zeile \u201edemoted self\u201c besagt genau das. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/4a8eca27689546b4b0fc3c666a3c37c4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wenn wir uns die Ereignisse ansehen, die dem Failover vorausgingen, k\u00f6nnen wir die Gr\u00fcnde erkennen, die das Problem f\u00fcr die Fortsetzung der Arbeit des Masters verursacht haben. <\/p>\n<p><\/p>\n<p>Wenn wir die Protokolle von Patroni betrachten, sehen wir eine Vielzahl von Fehlern, Timeouts, d. h. der Patroni-Agent kann nicht mit dem DCS arbeiten. In diesem Fall ist es der Consul-Agent, mit dem \u00fcber den Port 8500 kommuniziert wird. <\/p>\n<p><\/p>\n<p>Das Problem hierbei ist, dass Patroni und die Datenbank auf dem gleichen Host ausgef\u00fchrt werden. Und auf demselben Knoten liefen die Consul-Server. Indem wir eine Belastung auf dem Server erzeugten, schufen wir Probleme auch f\u00fcr <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/de\/server\/\"   title=\"Server\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1515\">Server<\/a> Consul. Sie konnten nicht richtig kommunizieren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/0d8dba6641809560e6b32825d481e30b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nach einer gewissen Zeit, als die Last nachgelassen hatte, konnte unser Patroni wieder mit den Agenten kommunizieren. Die normale Funktion wurde wiederhergestellt. Und derselbe Server Pgdb-2 wurde erneut zum Master. Das hei\u00dft, es gab einen kurzen Flip, aufgrund dessen der Knoten seine Befugnisse als Master niederlegte und dann wieder \u00fcbernahm, d. h. alles kehrte zu dem zur\u00fcck, was es war. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/131b93e0bd83099e1b99b53742419e13.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und das kann als Fehlalarm betrachtet werden, oder man kann argumentieren, dass Patroni alles richtig gemacht hat. Das hei\u00dft, er erkannte, dass er den Zustand des Clusters nicht aufrechterhalten kann und legte seine Befugnisse nieder.<\/p>\n<p><\/p>\n<p>Und hier entstand das Problem, weil die Consul-Server auf derselben Hardware wie die Datenbanken laufen. Folglich wirkt sich jede Belastung \u2013 sei es eine Belastung der Festplatten oder Prozessoren \u2013 auch auf die Interaktion mit dem Consul-Cluster aus.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/142c7cf839c8da078451f7ba9d5499e5.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben entschieden, dass dies nicht zusammenleben sollte, und haben ein separates Cluster f\u00fcr Consul eingerichtet. Patroni arbeitete also bereits mit einem separaten Consul, d. h. einem separaten Postgres-Cluster und einem separaten Consul-Cluster. Dies ist eine grundlegende Anleitung, wie man all diese Dinge getrennt halten sollte, damit sie nicht zusammenleben. <\/p>\n<p><\/p>\n<p>Als Option k\u00f6nnte man die Parameter ttl, loop_wait, retry_timeout anpassen, d. h. versuchen, durch die Erh\u00f6hung dieser Parameter diese kurzfristigen Lastspitzen zu \u00fcberstehen. Aber das ist nicht die beste L\u00f6sung, denn diese Belastung kann \u00fcber einen l\u00e4ngeren Zeitraum anhalten. Und wir w\u00fcrden einfach \u00fcber die Grenzen dieser Parameter hinausgehen. Das k\u00f6nnte nicht wirklich hilfreich sein. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/c51f35dcd88b1c792acec231c0c6c66c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Das erste Problem, wie Sie verstanden haben, ist einfach. Wir haben die DCS zusammen mit der Datenbank platziert und dadurch ein Problem verursacht. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/cc2a98d9790441577fb4080406cbc53f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Das zweite Problem \u00e4hnelt dem ersten. Es ist \u00e4hnlich, weil wir erneut Schwierigkeiten mit der Interaktion mit dem DCS-System haben.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/e5c01b105adca48cc620085db8dd2d2b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wenn wir die Protokolle betrachten, sehen wir, dass erneut ein Kommunikationsfehler aufgetreten ist. Und Patroni sagt, dass ich nicht mit dem DCS kommunizieren kann, weshalb der aktuelle Master in den Replikat-Modus wechselt.<\/p>\n<p><\/p>\n<p>Der alte Master wird zum Replikat, hier funktioniert Patroni wie vorgesehen. Er startet pg_rewind, um das Transaktionsprotokoll zur\u00fcckzusetzen und sich dann mit dem neuen Master zu verbinden und ihn einzuholen. Hier funktioniert Patroni, wie es ihm zusteht. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/29255f4790abb15b64dbf9ee0b41c7fc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier m\u00fcssen wir den Ort finden, der dem File Error vorausging, also die Fehler, die der Grund daf\u00fcr waren, warum der File Error aufgetreten ist. In dieser Hinsicht ist es sehr praktisch, mit den Protokollen von Patroni zu arbeiten. Er schreibt in bestimmten Intervallen dieselben Nachrichten. Und wenn wir beginnen, diese Protokolle schnell durchzugehen, sehen wir, dass sich die Protokolle ge\u00e4ndert haben, was bedeutet, dass irgendwelche Probleme aufgetreten sind. Wir gehen schnell an diesen Ort zur\u00fcck und schauen, was passiert. <\/p>\n<p><\/p>\n<p>In einer normalen Situation sehen die Protokolle etwa so aus. Der Besitzer der Sperre wird \u00fcberpr\u00fcft. Und wenn der Besitzer zum Beispiel gewechselt hat, k\u00f6nnen bestimmte Ereignisse eintreten, auf die Patroni reagieren muss. In diesem Fall ist bei uns jedoch alles in Ordnung. Wir suchen nach dem Zeitpunkt, als die Fehler auftraten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f48ebd22a405f5b2900621451c68f543.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und wenn wir bis zu dem Punkt zur\u00fcckspulen, an dem die Fehler begannen, sehen wir, dass wir einen Auto-Failer hatten. Und da unsere Fehler mit der Interaktion mit DCS verbunden waren und wir in unserem Fall Consul verwendet haben, schauen wir uns auch die Protokolle von Consul an, um zu sehen, was dort passiert ist. <\/p>\n<p><\/p>\n<p>Bei einer groben \u00dcbereinstimmung der Zeit des Failers mit der Zeit in den Protokollen von Consul sehen wir, dass unsere Nachbarn im Consul-Cluster zu zweifeln begannen, ob es andere Mitglieder des Consul-Clusters gibt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/63b02ac5b4f5a34a2822f1eee2b1f2f8.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und wenn wir uns die Protokolle anderer Consul-Agenten ansehen, sehen wir ebenfalls, dass dort ein gewisser Netzwerk-Collapse stattfindet. Alle Mitglieder des Consul-Clusters zweifeln an der Existenz des anderen. Dies war der Ausl\u00f6ser f\u00fcr den Failer. <\/p>\n<p><\/p>\n<p>Wenn wir uns anschauen, was vor diesen Fehlern passiert ist, sehen wir verschiedene Fehler, wie z. B. Deadline, RPC fehlgeschlagen, d. h. es gibt eindeutig ein Problem bei der Interaktion der Mitglieder des Consul-Clusters. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b15c912f2afb49d9d85e7bb9361ce449.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Die einfachste Antwort ist, das Netzwerk zu reparieren. Aber es ist einfach, dies von der Trib\u00fcne aus zu sagen. Die Umst\u00e4nde sind jedoch so, dass der Kunde sich nicht immer leisten kann, das Netzwerk zu reparieren. Er k\u00f6nnte sich im Rechenzentrum befinden und m\u00f6glicherweise keine M\u00f6glichkeit haben, das Netzwerk zu reparieren oder auf die Hardware Einfluss zu nehmen. Daher sind andere Optionen n\u00f6tig. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/1dbdb66233acc3bc321a30a1c5fe14f9.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Es gibt Optionen:<\/p>\n<p><\/p>\n<ul>\n<li>Die einfachste M\u00f6glichkeit, die meines Erachtens sogar in der Dokumentation steht, besteht darin, die Consul-\u00dcberpr\u00fcfungen zu deaktivieren, d. h. einfach ein leeres Array zu \u00fcbergeben. Damit sagen wir dem Consul-Agenten, keine \u00dcberpr\u00fcfungen durchzuf\u00fchren. Durch diese \u00dcberpr\u00fcfungen k\u00f6nnen wir diese Netzwerkst\u00fcrme ignorieren und den Failer nicht ausl\u00f6sen. <\/li>\n<li>Eine andere M\u00f6glichkeit besteht darin, den raft_multiplier zu \u00fcberpr\u00fcfen. Dies ist ein Parameter des Consul-Servers. Standardm\u00e4\u00dfig ist er auf den Wert 5 eingestellt. Dieser Wert wird in der Dokumentation f\u00fcr Staging-Umgebungen empfohlen. Im Grunde beeinflusst dieser Parameter die H\u00e4ufigkeit des Nachrichtenaustauschs zwischen den Mitgliedern des Consul-Netzwerks. Tats\u00e4chlich hat dieser Parameter Einfluss auf die Geschwindigkeit der Kommunikation zwischen den Mitgliedern des Consul-Clusters. F\u00fcr Produktionsumgebungen wird empfohlen, ihn zu verringern, damit die Knoten h\u00e4ufiger Nachrichten austauschen. <\/li>\n<li>Eine andere Option, die wir begonnen haben zu nutzen, ist die Erh\u00f6hung der Priorit\u00e4t der Consul-Prozesse im Vergleich zu anderen Prozessen f\u00fcr den Prozessscheduler des Betriebssystems. Es gibt einen solchen Parameter namens \u201enice\u201c, der genau die Priorit\u00e4t der Prozesse definiert, die der Betriebssystem-Scheduler bei der Planung ber\u00fccksichtigt. Wir haben den Consul-Agenten den Wert von nice verringert, d.h. die Priorit\u00e4t erh\u00f6ht, damit das Betriebssystem den Consul-Prozessen mehr Zeit f\u00fcr die Ausf\u00fchrung ihrer Arbeit und ihres Codes einr\u00e4umt. In unserem Fall hat dies unser Problem gel\u00f6st. <\/li>\n<li>Eine andere Option ist, Consul nicht zu verwenden. Ich habe einen Kollegen, der ein gro\u00dfer Bef\u00fcrworter von Etcd ist. Und wir streiten uns regelm\u00e4\u00dfig dar\u00fcber, was besser ist \u2013 Etcd oder Consul. Aber in Bezug darauf, was besser ist, sind wir uns normalerweise einig, dass Consul einen Agenten hat, der auf jedem Knoten mit der Datenbank laufen muss. Das hei\u00dft, die Interaktion von Patroni mit dem Consul-Cluster erfolgt \u00fcber diesen Agenten. Und dieser Agent wird zum Engpass. Wenn mit dem Agenten etwas passiert, kann Patroni nicht mehr mit dem Consul-Cluster arbeiten. Das ist ein Problem. Bei Etcd gibt es keinen Agenten. Patroni kann direkt mit der Liste der Etcd-Server arbeiten und mit ihnen kommunizieren. Wenn Sie also in Ihrem Unternehmen Etcd verwenden, w\u00e4re Etcd wahrscheinlich die bessere Wahl als Consul. Aber bei unseren Kunden sind wir immer durch das eingeschr\u00e4nkt, was der Kunde gew\u00e4hlt und verwendet hat. Und bei unseren Kunden verwenden die meisten Consul. <\/li>\n<li>Und der letzte Punkt ist, die Werte der Parameter zu \u00fcberpr\u00fcfen. Wir k\u00f6nnen diese Parameter nach oben anpassen in der Hoffnung, dass unsere kurzfristigen Netzwerkprobleme kurz bleiben und nicht den Zeitraum dieser Parameter \u00fcberschreiten. Auf diese Weise k\u00f6nnen wir die Aggressivit\u00e4t von Patroni bei der Ausf\u00fchrung des automatischen Failovers verringern, wenn irgendwelche Netzwerkprobleme auftreten.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f0043050da20f6368dabf66ec9a4eade.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich denke, viele, die Patroni verwenden, sind mit diesem Befehl vertraut. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/9f78f59dab166e47ac78436802156d04.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dieser Befehl zeigt den aktuellen Zustand des Clusters an. Und auf den ersten Blick k\u00f6nnte dieses Bild normal erscheinen. Wir haben einen Master, wir haben eine Replik, es gibt keine Replikationsverz\u00f6gerung. Aber dieses Bild ist genau so lange normal, bis wir wissen, dass in diesem Cluster drei Knoten und nicht zwei sein sollten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a39c891f8620ba210b6bce0727e0fa8b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In diesem Zusammenhang gab es einen Auto-Failover. Und nach diesem Auto-Failover ist unsere Replikation verschwunden. Wir m\u00fcssen herausfinden, warum sie verschwunden ist, und sie zur\u00fcckbringen, wiederherstellen. Und wir schauen erneut in die Logs und sehen, warum wir einen Auto-Failover hatten.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/e6e67d46cb20c8d7e58c7505157f68e1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In diesem Fall wurde die zweite Replikation zum Master. Hier ist alles in Ordnung. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b86ccea68b0c6013a23bbd2804e48320.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und wir m\u00fcssen uns die Replikation anschauen, die abgebrochen ist und die nicht im Cluster ist. Wir \u00f6ffnen die Patroni-Logs und sehen, dass wir beim Verbinden mit dem Cluster ein Problem in der Phase pg_rewind hatten. Um sich mit dem Cluster zu verbinden, muss das Transaktionsprotokoll zur\u00fcckgedreht, das erforderliche Transaktionsprotokoll vom Master angefordert und dann der Master eingeholt werden. <\/p>\n<p><\/p>\n<p>In diesem Fall haben wir kein Transaktionsprotokoll und die Replikation kann nicht gestartet werden. Folglich stoppen wir PostgreSQL mit einem Fehler. Deshalb ist sie nicht im Cluster. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/dadbd44b766674b719d85781ef7f0caa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir m\u00fcssen verstehen, warum sie nicht im Cluster ist und warum keine Protokolle vorhanden sind. Wir gehen zum neuen Master und sehen, was in seinen Protokollen steht. Es stellt sich heraus, dass beim pg_rewind ein Checkpoint stattfand. Und ein Teil der alten Transaktionsprotokolle wurde einfach umbenannt. Als der alte Master versuchte, sich mit dem neuen Master zu verbinden und diese Protokolle anzufordern, waren sie bereits umbenannt, sie waren einfach nicht mehr vorhanden.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f2d5c37324f9436b2bdad1290612d86f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich habe die Zeitstempel verglichen, als diese Ereignisse stattfanden. Und dort betr\u00e4gt der Unterschied gerade einmal 150 Millisekunden, d.h. der Checkpoint wurde in 369 Millisekunden abgeschlossen, die WAL-Segmente wurden umbenannt. Und ungef\u00e4hr 517 Millisekunden sp\u00e4ter, nach 150 Millisekunden, wurde das Rewind auf der alten Replikation gestartet. D.h. es reichten buchst\u00e4blich 150 Millisekunden aus, damit die Replikation sich nicht verbinden und laufen konnte. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/99dd80deb8466bfc3aff568456e07102.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Was sind die Optionen?<\/p>\n<p><\/p>\n<p>Anfangs haben wir Replikationsslots verwendet. Wir dachten, das w\u00e4re gut. Obwohl wir in der ersten Phase des Einsatzes die Slots deaktiviert haben. Wir hatten das Gef\u00fchl, wenn die Slots viele WAL-Segmente ansammeln, k\u00f6nnten wir den Master zum Absturz bringen. Er w\u00fcrde abst\u00fcrzen. Wir haben eine Zeit lang ohne Slots gek\u00e4mpft. Und haben verstanden, dass wir Slots ben\u00f6tigen, also haben wir die Slots zur\u00fcckgebracht. <\/p>\n<p><\/p>\n<p>Es gibt jedoch ein Problem: Wenn der Master in die Replikation wechselt, entfernt er die Slots und dabei auch die WAL-Segmente. Um das Auftreten dieses Problems auszuschlie\u00dfen, haben wir den Parameter wal_keep_segments erh\u00f6ht. Er betr\u00e4gt standardm\u00e4\u00dfig 8 Segmente. Wir haben ihn auf 1.000 erh\u00f6ht und geschaut, wie viel Speicherplatz wir haben. Und wir haben 16 Gigabyte f\u00fcr wal_keep_segments bereitgestellt. Das hei\u00dft, beim Wechseln haben wir in allen Knoten immer einen Puffer von 16 Gigabyte Transaktionsprotokollen.<\/p>\n<p><\/p>\n<p>Und zus\u00e4tzlich \u2013 das ist auch f\u00fcr l\u00e4ngere Wartungsarbeiten relevant. Angenommen, wir m\u00fcssen eine der Replikate aktualisieren. Und wir m\u00f6chten sie ausschalten. Wir m\u00fcssen m\u00f6glicherweise die Software aktualisieren, vielleicht das Betriebssystem, oder etwas anderes. Wenn wir die Replik abschalten, wird f\u00fcr diese Replik auch der Slot entfernt. Und wenn wir eine kleine Anzahl von wal_keep_segments verwenden, werden bei l\u00e4ngerer Abwesenheit der Replik die Transaktionsprotokolle gespielt. Wir starten die Replik neu, sie fordert die Transaktionsprotokolle an, bei denen sie angehalten hat, aber auf dem Master k\u00f6nnten sie nicht mehr vorhanden sein. Und die Replik kann sich ebenfalls nicht verbinden. Daher halten wir einen gro\u00dfen Puffer von Protokollen bereit.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/dad55c828128ce92f649a99cc53ce54b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/63e70f0b098567f3a6d4fd66a0c293bb.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben eine Produktionsdatenbank. Dort laufen bereits Projekte. <\/p>\n<p><\/p>\n<p>Ein File-War ist aufgetreten. Wir sind hineingegangen und haben geschaut \u2013 alles in Ordnung, die Replikate sind da, es gibt keine Replikationsverz\u00f6gerung. Auch keine Fehler in den Protokollen, alles in Ordnung. <\/p>\n<p><\/p>\n<p>Das Produktteam sagt, dass da eigentlich einige Daten vorhanden sein sollten, aber wir sehen sie nur in einer Quelle, und in der Datenbank sehen wir sie nicht. Und wir m\u00fcssen herausfinden, was mit ihnen passiert ist. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/568ca9aa31680d5e0c9d4ed9693b14e6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Es ist klar, dass pg_rewind sie \u00fcberschrieben hat. Das haben wir sofort verstanden, aber wir haben nachgesehen, was passiert ist. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a8fee389201d96e81761cd276c5265c3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In den Logs k\u00f6nnen wir immer feststellen, wann der File-War aufgetreten ist, wer Master geworden ist, und wir k\u00f6nnen feststellen, wer der alte Master war und wann er sich entscheiden wollte, Replik zu werden. Das hei\u00dft, wir ben\u00f6tigen diese Logs, um das Volumen der verlorenen Transaktionsprotokolle zu kl\u00e4ren.<\/p>\n<p><\/p>\n<p>Unser alter Master wurde neu gestartet. Und im Autostart war Patroni eingetragen. Patroni wurde gestartet. Daraufhin startete er Postgres. Genauer gesagt, vor dem Start von Postgres und bevor er ihn zur Replik machte, startete Patroni den pg_rewind-Prozess. Entsprechend hat er einen Teil der Transaktionsprotokolle gel\u00f6scht, neue heruntergeladen und sich verbunden. Hier hat Patroni gro\u00dfartig funktioniert, wie es sein sollte. Unser Cluster wurde wiederhergestellt. Wir hatten 3 Knoten, nach dem File-Verlust waren es 3 Knoten \u2013 alles super. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b747a24f53e20ed098c2dc0afc79bead.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben einen Teil der Daten verloren. Und wir m\u00fcssen herausfinden, wie viel wir verloren haben. Wir suchen genau den Moment, in dem wir einen Rewind hatten. Wir k\u00f6nnen dies anhand solcher Protokolle finden. Der Rewind wurde gestartet, hat etwas gemacht und wurde beendet.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/5b7bacffb52e3ccd529a3a734c441295.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir m\u00fcssen die Position im Transaktionsprotokoll finden, an der der alte Master angehalten hat. In diesem Fall ist das dieser Punkt hier. Und wir ben\u00f6tigen den zweiten Punkt, d. h. den Unterschied, wie weit der alte Master vom neuen abweicht. <\/p>\n<p><\/p>\n<p>Wir verwenden den normalen pg_wal_lsn_diff und vergleichen diese beiden Punkte. Und in diesem Fall erhalten wir 17 Megabyte. Ob das viel oder wenig ist, entscheidet jeder f\u00fcr sich selbst. Denn f\u00fcr manche sind 17 Megabyte wenig, f\u00fcr andere ist das viel und inakzeptabel. Hier bestimmt jeder individuell entsprechend den Gesch\u00e4ftserfordernissen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/55335fce85961e159459c38300a0ad12.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aber was haben wir f\u00fcr uns herausgefunden? <\/p>\n<p><\/p>\n<p>Zun\u00e4chst m\u00fcssen wir f\u00fcr uns entscheiden, ob der Autostart von Patroni nach einem Systemneustart immer erforderlich ist. Oftmals m\u00fcssen wir auf den alten Master zugreifen, um zu sehen, wie weit er sich entfernt hat. Vielleicht auch die Segmente des Transaktionsprotokolls inspizieren, um zu sehen, was dort ist. Und herausfinden, ob wir diese Daten verlieren k\u00f6nnen oder ob wir den alten Master im Standalone-Modus starten m\u00fcssen, um diese Daten abzurufen. <\/p>\n<p><\/p>\n<p>Und erst danach sollten wir die Entscheidung treffen, ob wir diese Daten verwerfen k\u00f6nnen oder ob wir sie wiederherstellen k\u00f6nnen, indem wir diesen Knoten als Replik in unser Cluster einf\u00fcgen.<\/p>\n<p><\/p>\n<p>Dar\u00fcber hinaus gibt es den Parameter \u201emaximum_lag_on_failover\u201c. Standardm\u00e4\u00dfig hat dieser Parameter, wenn ich mich nicht irre, einen Wert von 1 Megabyte. <\/p>\n<p><\/p>\n<p>Wie funktioniert das? Wenn unsere Replik bei der Replikationsverz\u00f6gerung um 1 Megabyte Daten zur\u00fcckliegt, nimmt diese Replik nicht an den Wahlen teil. Und wenn pl\u00f6tzlich ein Failover eintritt, schaut Patroni, welche Replikas zur\u00fcckliegen. Wenn sie um eine gro\u00dfe Menge an Transaktionsprotokollen zur\u00fcckliegen, k\u00f6nnen sie nicht Master werden. Das ist eine sehr gute Schutzfunktion, die hilft, viele Datenverluste zu vermeiden. <\/p>\n<p><\/p>\n<p>Aber es gibt ein Problem, dass die Replikationsverz\u00f6gerung im Patroni-Cluster und DCS in bestimmten Intervallen aktualisiert wird. Meines Erachtens betr\u00e4gt der Standardwert f\u00fcr ttl 30 Sekunden.<\/p>\n<p><\/p>\n<p>Entsprechend kann es Situationen geben, in denen die Replikationsverz\u00f6gerung f\u00fcr Replikate in DCS gleich ist, die tats\u00e4chliche Verz\u00f6gerung jedoch ganz anders oder m\u00f6glicherweise \u00fcberhaupt nicht vorhanden ist, d. h. das Ganze ist nicht in Echtzeit. Und es reflektiert nicht immer das tats\u00e4chliche Bild. Man sollte darauf keine ausgekl\u00fcgelte Logik aufbauen. <\/p>\n<p><\/p>\n<p>Und das Risiko von Datenverlusten bleibt immer bestehen. Im schlimmsten Fall eine Formel, im Durchschnitt eine andere. D. h. wenn wir die Implementierung von Patroni planen und einsch\u00e4tzen, wie viele Daten wir verlieren k\u00f6nnen, m\u00fcssen wir auf diese Formeln setzen und uns ungef\u00e4hr vorstellen, wie viele Daten wir verlieren k\u00f6nnten. <\/p>\n<p><\/p>\n<p>Und es gibt eine gute Nachricht. Wenn der alte Master vorangegangen ist, kann er aufgrund bestimmter Hintergrundprozesse vorangekommen sein. D. h. es gab m\u00f6glicherweise einen Auto-Vakuum, der Daten geschrieben und in das Transaktionsprotokoll gespeichert hat. Und diese Daten k\u00f6nnen wir problemlos ignorieren und verlieren. Das ist kein Problem. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a86e8971ab4ef41b89af9cf0bdf519ba.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und so sehen die Protokolle aus, wenn maximum_lag_on_failover festgelegt ist und ein Failover stattgefunden hat, und es notwendig ist, einen neuen Master auszuw\u00e4hlen. Die Replik bewertet sich selbst als unf\u00e4hig, an den Wahlen teilzunehmen. Und sie lehnt die Teilnahme am Wettlauf um die F\u00fchrungsposition ab. Stattdessen wartet sie darauf, dass ein neuer Master gew\u00e4hlt wird, um sich dann ihm anzuschlie\u00dfen. Dies ist eine zus\u00e4tzliche Ma\u00dfnahme zum Schutz vor Datenverlusten.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f760788e5951facdd08b2069037830fa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/c32f26e7526e1873f3bfd7d3693fcc72.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier hat unser Produktteam berichtet, dass ihr Produkt Probleme mit Postgres hat. Dabei kann man nicht auf den Master zugreifen, da er per SSH nicht erreichbar ist. Und ein Auto-Failover erfolgt auch nicht. <\/p>\n<p><\/p>\n<p>Dieser Host wurde zwangsweise neu gestartet. Aufgrund des Neustarts kam es zu einem Auto-Failover, obwohl man auch einen manuellen Auto-Failover h\u00e4tte durchf\u00fchren k\u00f6nnen, wie ich jetzt verstehe. Und nach dem Neustart schauen wir uns an, was mit dem aktuellen Master war. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/95efb82e0647a396a21683cd53a69547.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dabei wussten wir im Voraus, dass wir Probleme mit den Festplatten hatten, d. h. wir wussten bereits durch das Monitoring, wo wir nachforschen und was wir suchen mussten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/367aaab607d833d96a573ddbbbced502.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben uns in das Postgres-Protokoll eingeklinkt und angefangen, zu sehen, was dort passiert. Wir haben Commits gesehen, die dort ein bis zwei oder drei Sekunden dauern, was \u00fcberhaupt nicht normal ist. Wir haben bemerkt, dass unser Auto-Vakuum sehr lange und seltsam gestartet wird. Und wir haben tempor\u00e4re Dateien auf der Festplatte gesehen. D. h. das sind alles Anzeichen f\u00fcr Probleme mit den Festplatten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/7e0cfce7a81901ef9ef736c3fefc8dce.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben das System-Dmesg (das Log der Kernelmeldungen) \u00fcberpr\u00fcft und festgestellt, dass wir ein Problem mit einer der Festplatten haben. Das Festplattensystem stellte ein Software-RAID dar. Wir haben \/proc\/mdstat angesehen und gesehen, dass uns eine Festplatte fehlt. Das hei\u00dft, hier ist ein RAID aus 8 Festplatten, und uns fehlt eine. Wenn man sich die Folie genau ansieht, kann man im Output erkennen, dass uns sde fehlt. Wir haben, um es vereinfacht auszudr\u00fccken, eine Festplatte verloren. Das hat Festplattenprobleme ausgel\u00f6st, und die Anwendungen hatten ebenfalls Schwierigkeiten im Umgang mit dem Postgres-Cluster.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/4b09b3aa761cb504fa79173ef280faac.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In diesem Fall h\u00e4tte uns Patroni nicht geholfen, da Patroni nicht daf\u00fcr zust\u00e4ndig ist, den Status des Servers oder der Festplatte zu \u00fcberwachen. Wir m\u00fcssen solche Situationen mit externem Monitoring verfolgen. Wir haben zu unserem externen Monitoring die \u00dcberwachung der Festplatten schnell hinzugef\u00fcgt. <\/p>\n<p><\/p>\n<p>Und wir hatten den Gedanken - k\u00f6nnte uns Fencing oder ein Software-Watchdog helfen? Wir dachten, dass es in diesem Fall wenig hilfreich gewesen w\u00e4re, da Patroni w\u00e4hrend der Probleme weiterhin mit dem DCS-Cluster interagierte und keine Probleme sah. Das hei\u00dft, aus der Sicht von DCS und Patroni lief alles gut im Cluster, obwohl es tats\u00e4chlich Probleme mit der Festplatte und der Verf\u00fcgbarkeit der Datenbank gab. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/15fdac78535355d4eb889efcc27efc46.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Meiner Meinung nach ist das eines der seltsamsten Probleme, die ich sehr lange untersucht habe; ich habe unz\u00e4hlige Logs gelesen, durchgearbeitet und habe es den Cluster-Simulator genannt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b5259774931c290eda6673deb14b6c48.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Das Problem war, dass der alte Master nicht zu einer normalen Replik werden konnte, das hei\u00dft, Patroni startete ihn und zeigte, dass dieser Knoten als Replik vorhanden ist, aber gleichzeitig war er keine normale Replik. Jetzt werdet ihr sehen, warum. Ich habe das von der Problemanalyse behalten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/c35a5d102a46764bbf96e5a75ee88171.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und wie alles begann? Wie bei dem vorherigen Problem begann es mit Festplattensperren. Wir hatten eine bis zwei Commits pro Sekunde. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/435c1b350a89f288e0e10ca9d5a2ec6e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Es gab Verbindungsabbr\u00fcche, das hei\u00dft, die Clients wurden getrennt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/920cb1f3f3b40578e15e6ff711e85c50.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Es gab Sperren unterschiedlichen Schweregrades. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/285d6292d89b928a85e95602ee57d38a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und folglich war das Festplattensystem nicht sehr reaktionsschnell. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ebe71d49360e7f604ecd6a3c8276cb73.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und das mysteri\u00f6seste f\u00fcr mich war die eingetroffene sofortige Herunterfahranforderung. Postgres hat drei Abschaltmodi:<\/p>\n<p><\/p>\n<ul>\n<li>Das ist 'graceful', wenn wir warten, bis sich alle Clients selbstst\u00e4ndig abmelden. <\/li>\n<li>Es gibt 'fast', wenn wir die Clients zwingen, sich abzumelden, weil wir das Herunterfahren einleiten. <\/li>\n<li>Und sofort. In diesem Fall informiert immediate die Kunden nicht einmal dar\u00fcber, dass sie sich abmelden m\u00fcssen, es schaltet sich einfach ohne Vorwarnung aus. Und an alle Kunden sendet das Betriebssystem eine RST-Nachricht (TCP-Nachricht, dass die Verbindung unterbrochen ist und der Kunde nichts mehr holen kann). <\/li>\n<\/ul>\n<p><\/p>\n<p>Wer hat dieses Signal gesendet? Hintergrundprozesse von Postgres senden sich gegenseitig solche Signale nicht, d. h. es ist ein kill-9. Sie senden sich untereinander so etwas nicht, sie reagieren nur darauf, d. h. es ist ein Notneustart von Postgres. Ich wei\u00df nicht, wer es gesendet hat. <\/p>\n<p><\/p>\n<p>Ich habe das mit dem Befehl \u201elast\u201c \u00fcberpr\u00fcft und ich habe eine Person gesehen, die sich zusammen mit uns auf diesem Server angemeldet hat, aber ich habe mich nicht getraut, die Frage zu stellen. M\u00f6glicherweise war es kill -9. Ich h\u00e4tte in den Logs kill -9 gesehen, da Postgres schreibt, dass es kill -9 akzeptiert hat, aber ich habe das nicht in den Logs gesehen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fe8e844649cea3384ebfde86e36eba44.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Als ich weiter nachforschte, stellte ich fest, dass Patroni ziemlich lange keine Logs geschrieben hat \u2013 54 Sekunden. Und wenn man die beiden Zeitstempel vergleicht, gab es hier ungef\u00e4hr 54 Sekunden lang keine Nachrichten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ffb1c4db3d7de591d77d56ed2fcc4f2a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und in dieser Zeit fand ein automatischer Failover statt. Patroni hat hier wieder einmal hervorragend gearbeitet. Unser alter Master war nicht verf\u00fcgbar, irgendetwas passierte mit ihm. Und es begann die Wahl eines neuen Masters. Hier hat alles gut funktioniert. Unser pgsql01 wurde neuer Leader. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/6b2457653e9f77af44cd64b4aff021a0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wir haben eine Replik, die zum Master wurde. Und es gibt eine zweite Replik. Und mit der zweiten Replik gab es genau Probleme. Sie versuchte, sich neu zu konfigurieren. So wie ich es verstehe, wollte sie die recovery.conf \u00e4ndern, Postgres neu starten und sich mit dem neuen Master verbinden. Sie meldet alle 10 Sekunden, dass sie es versucht, aber es nicht klappt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/381818f189e19c3e1154074b4652f837.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und w\u00e4hrend dieser Versuche kam das immediate-shutdown-Signal zum alten Master. Der Master wird neu gestartet. Und das Recovery wird ebenfalls gestoppt, weil der alte Master sich in den Neustart begibt. Das bedeutet, dass die Replik sich nicht mit ihm verbinden kann, weil er sich im Ausschaltmodus befindet. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/d8a8cde925fa8fe601d44ab908ae69dc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Irgendwann hat es funktioniert, aber die Replikation wurde dabei nicht gestartet. <\/p>\n<p><\/p>\n<p>Ich habe nur eine Hypothese, dass in der recovery.conf die Adresse des alten Masters war. Und als der neue Master erschien, versuchte die zweite Replik weiterhin, sich mit dem alten Master zu verbinden. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/425ea3af1f1e186f4760e1fb1f5419fa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Als Patroni auf der zweiten Replik startete, wurde der Knoten gestartet, konnte sich aber nicht \u00fcber die Replikation verbinden. Und es entstand ein Replikationsr\u00fcckstand, der ungef\u00e4hr so aussah. Das hei\u00dft, alle drei Knoten waren vorhanden, aber der zweite Knoten blieb zur\u00fcck. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f564eacd9944666c9a3f5bea634ede6b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wenn man jedoch die Protokolle betrachtet, die aufgezeichnet wurden, konnte man sehen, dass die Replikation nicht starten kann, weil die Transaktionsprotokolle unterschiedlich sind. Die Transaktionsprotokolle, die vom Master angeboten werden und die in recovery.conf angegeben sind, passen einfach nicht zu unserem aktuellen Knoten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/6b09947d157c9ef0a190da2df2cb5892.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier habe ich einen Fehler gemacht. Ich h\u00e4tte kommen sollen, um mir anzusehen, was in recovery.conf steht, um meine Hypothese zu \u00fcberpr\u00fcfen, dass wir uns nicht mit dem richtigen Master verbinden. Aber ich hatte mich gerade erst damit besch\u00e4ftigt und es kam mir nicht in den Sinn, oder ich sah, dass die Replikation zur\u00fccklag und sie neu gestartet werden musste. Ich habe das irgendwie nachl\u00e4ssig erledigt. Das war mein Fehler. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/159f2256fd81428fd0d82a255528887d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nach 30 Minuten kam der Admin, d. h. ich startete Patroni auf der Replik. Ich hatte bereits auf sie verzichtet, ich dachte, ich m\u00fcsste sie neu starten. Und ich dachte - ich starte Patroni neu, vielleicht funktioniert es ja. Die Wiederherstellung wurde gestartet. Und die Datenbank \u00f6ffnete sich sogar, sie war bereit, Verbindungen entgegenzunehmen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/aeac98750386c8389d39e006a229cc85.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Die Replikation startete. Aber nach einer Minute fiel sie mit dem Fehler aus, dass die Transaktionsprotokolle nicht passen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/17eaba000a79c80c29d1bc3902de05e6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich dachte, ich starte es noch einmal neu. Ich startete Patroni erneut, wobei ich Postgres nicht neu startete, sondern nur Patroni neu startete, in der Hoffnung, dass es die Datenbank auf magische Weise startet. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a85b38e033c45ad73da317f41e0ef24a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Die Replikation startete erneut, aber die Eintr\u00e4ge im Transaktionsprotokoll waren unterschiedlich, sie waren nicht dieselben wie bei dem vorherigen Startversuch. Die Replikation stoppte wieder. Die Fehlermeldung war bereits etwas anders und war f\u00fcr mich nicht besonders informativ. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fd90d708230bd54af685786c7e361ee1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und hier kam mir der Gedanke \u2013 was w\u00e4re, wenn ich Postgres neu starte und gleichzeitig einen Checkpoint auf dem aktuellen Master mache, um den Punkt in den Transaktionsprotokollen ein kleines St\u00fcck nach vorne zu schieben, damit die Wiederherstellung von einem anderen Moment beginnt? Au\u00dferdem hatten wir noch etwas WAL-Backup. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/19e67f95d1a74141a013947c9aa39e38.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ich startete Patroni neu, machte ein paar Checkpoints auf dem Master, ein paar Restart-Punkte auf der Replik, als sie sich \u00f6ffnete. Und das half. Ich dachte lange dar\u00fcber nach, warum das half und wie es funktionierte. Und die Replik startete. Und die Replikation riss nicht mehr ab. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/418ca59a681be84f51ed374a73a759c9.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dieses Problem geh\u00f6rt f\u00fcr mich zu den r\u00e4tselhaftesten, \u00fcber das ich immer noch nachgr\u00fcble, was da tats\u00e4chlich passiert ist. <\/p>\n<p><\/p>\n<p>Welche Schlussfolgerungen lassen sich hier ziehen? Patroni kann wie vorgesehen ohne Fehler funktionieren. Aber das ist keine 100 % Garantie, dass alles in Ordnung ist. Eine Replikation kann starten, kann sich jedoch im halbfunktionsf\u00e4higen Zustand befinden, und die Anwendung darf nicht mit einer solchen Replikation arbeiten, da dort alte Daten vorhanden sein k\u00f6nnten. <\/p>\n<p><\/p>\n<p>Und nach jedem Failover sollten wir immer pr\u00fcfen, ob mit dem Cluster alles in Ordnung ist, d.h. ob die erforderliche Anzahl an Replikaten vorhanden ist und ob es keinen Replikationsverzug gibt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/aca7047ff33d3efe14071b798b554091.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Und w\u00e4hrend ich diese Probleme betrachte, werde ich Empfehlungen formulieren. Ich habe versucht, sie in zwei Folien zu b\u00fcndeln. Wahrscheinlich h\u00e4tte man alle Geschichten in zwei Folien zusammenfassen und nur dar\u00fcber berichten k\u00f6nnen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/d4ad31b26d83c8846fe4097a11d70849.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wenn Sie Patroni verwenden, sollten Sie unbedingt \u00fcber eine \u00dcberwachung verf\u00fcgen. Sie sollten immer wissen, wann ein automatisches Failover stattgefunden hat, denn wenn Sie nicht wissen, dass ein automatisches Failover stattfand, kontrollieren Sie den Cluster nicht. Und das ist schlecht.<\/p>\n<p><\/p>\n<p>Nach jedem Failover m\u00fcssen wir den Cluster immer manuell \u00fcberpr\u00fcfen. Wir m\u00fcssen sicherstellen, dass wir immer die aktuelle Anzahl an Replikaten haben, keinen Replikationsverzug, und dass es keine Fehler in den Protokollen gibt, die mit der Streaming-Replikation, Patroni oder dem DCS-System zusammenh\u00e4ngen.<\/p>\n<p><\/p>\n<p>Die Automatisierung kann erfolgreich arbeiten, Patroni ist ein sehr gutes Werkzeug. Es kann funktionieren, aber das f\u00fchrt den Cluster nicht in den gew\u00fcnschten Zustand. Und wenn wir dar\u00fcber nicht informiert werden, werden wir Probleme bekommen.<\/p>\n<p><\/p>\n<p>Patroni ist keine Wunderwaffe. Wir m\u00fcssen trotzdem verstehen, wie Postgres funktioniert, wie die Replikation funktioniert und wie Patroni mit Postgres arbeitet und wie die Kommunikation zwischen den Knoten gew\u00e4hrleistet wird. Das ist notwendig, um manuell auftretende Probleme beheben zu k\u00f6nnen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ea4162df3561d2ea7001f2ef6788eaaa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wie gehe ich an das Thema Diagnostik heran? Es ist so, dass wir mit verschiedenen Kunden arbeiten und niemand hat einen ELK-Stack, sodass wir in den Protokollen nachschauen m\u00fcssen, indem wir 6 Konsolen und 2 Tabs \u00f6ffnen. In einem Tab sind die Protokolle von Patroni f\u00fcr jeden Knoten, im anderen Tab sind die Protokolle von Consul oder Postgres, wenn n\u00f6tig. Das Diagnostizieren ist sehr schwierig. <\/p>\n<p><\/p>\n<p>Welche Ans\u00e4tze habe ich entwickelt? Erstens, ich schaue immer, wann das Failover stattfand. Und das ist f\u00fcr mich eine Art Trennlinie. Ich achte darauf, was vor dem Failover, w\u00e4hrend des Failovers und nach dem Failover passiert ist. Ein Failover hat zwei Zeitmarken: den Beginn und das Ende. <\/p>\n<p><\/p>\n<p>Als N\u00e4chstes schaue ich in den Logs nach den Ereignissen vor dem Failover, was dem Failover vorangegangen ist, d. h. ich suche nach den Gr\u00fcnden, warum das Failover stattgefunden hat. <\/p>\n<p><\/p>\n<p>Und das gibt mir ein Bild davon, was passiert ist und was in Zukunft getan werden kann, um \u00e4hnliche Umst\u00e4nde zu vermeiden (und damit ein Failover zu verhindern).<\/p>\n<p><\/p>\n<p>Und wohin schauen wir normalerweise? Ich schaue:<\/p>\n<p><\/p>\n<ul>\n<li>Zuerst in die Logs von Patroni. <\/li>\n<li>Dann schaue ich mir die Logs von Postgres oder die DCS-Logs an, je nachdem, was in den Patroni-Logs gefunden wurde. <\/li>\n<li>Und auch die Systemlogs geben manchmal Aufschluss dar\u00fcber, was die Ursache f\u00fcr das Failover war. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a53618e366020e1a550d852fc308c188.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wie halte ich es mit Patroni? Ich halte viel von Patroni. Meiner Meinung nach ist es das Beste, was es heute gibt. Ich kenne viele andere Produkte: Stolon, Repmgr, Pg_auto_failover, PAF. Vier Werkzeuge. Ich habe sie alle ausprobiert. Patroni hat mir am besten gefallen. <\/p>\n<p><\/p>\n<p>Wenn man mich fragt: \"Empfehle ich Patroni?\", sage ich ja, denn Patroni gef\u00e4llt mir. Und ich habe das Gef\u00fchl, ich habe gelernt, wie man damit umgeht. <\/p>\n<p><\/p>\n<p>Wenn Sie interessiert sind zu sehen, welche anderen Probleme es mit Patroni gibt, au\u00dfer den von mir genannten, k\u00f6nnen Sie immer die Seite <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\/issues\/\">issues<\/a><\/noindex> auf GitHub besuchen. Dort gibt es viele verschiedene Geschichten und es werden viele interessante Probleme diskutiert. Letztendlich wurden einige Bugs erfasst und behoben, d. h. es ist eine interessante Lekt\u00fcre. <\/p>\n<p><\/p>\n<p>Dort gibt es interessante Geschichten dar\u00fcber, wie Menschen sich ins eigene Knie schie\u00dfen. Sehr lehrreich. Man liest und versteht, dass man es so nicht machen sollte. Ich habe mir einen Haken gesetzt. <\/p>\n<p><\/p>\n<p>Und ich m\u00f6chte dem Unternehmen Zalando ein gro\u00dfes Dankesch\u00f6n daf\u00fcr sagen, dass sie dieses Projekt vorantreiben, insbesondere Alexander Kukushkin und Alexey Klyukin. Alexey Klyukin ist einer der Mitautoren, er arbeitet nicht mehr bei Zalando, aber das sind die zwei Personen, die mit diesem Produkt begonnen haben. <\/p>\n<p><\/p>\n<p>Und ich halte Patroni f\u00fcr eine sehr coole Sache. Ich bin zufrieden, dass es existiert; es ist interessant, damit zu arbeiten. Ein gro\u00dfes Dankesch\u00f6n an alle Mitwirkenden, die Patches f\u00fcr Patroni schreiben. Ich hoffe, dass Patroni mit der Zeit reifer, cooler und funktionaler wird. Es funktioniert bereits gut, aber ich hoffe, dass es noch besser wird. Wenn Sie planen, Patroni bei sich einzusetzen, dann scheuen Sie sich nicht. Es ist eine gute L\u00f6sung, die man implementieren und nutzen kann. <\/p>\n<p><\/p>\n<p>Das ist alles. Wenn Sie Fragen haben, stellen Sie diese bitte.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Patroni Failure Stories oder wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/85c2fef2455999b48413c9fc3b235ed6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Fragen<\/p>\n<p><\/p>\n<p><em>Danke f\u00fcr den Vortrag! Wenn man nach dem Failover trotzdem sehr genau hinschauen muss, warum brauchen wir dann einen automatischen Failover?<\/em> <\/p>\n<p><\/p>\n<p>Weil es etwas Neues ist. Wir arbeiten erst seit einem Jahr damit. Man sollte lieber auf Nummer sicher gehen. Wir wollen reingehen und sehen, ob wirklich alles so funktioniert hat, wie es sollte. Das ist ein gewisses Ma\u00df an Erwachsensein, das Misstrauen \u2013 besser etwas mehr zu \u00fcberpr\u00fcfen und nachzusehen. <\/p>\n<p><\/p>\n<p><em>Zum Beispiel sind wir am Morgen reingegangen und haben nachgeschaut, oder?<\/em><\/p>\n<p><\/p>\n<p>Nicht am Morgen, wir erfahren normalerweise fast sofort vom Auto-Failer. Wir bekommen Benachrichtigungen, sehen, dass der Auto-Failer passiert ist. Wir schauen fast sofort nach. Aber all diese Pr\u00fcfungen sollten auf die Monitoring-Ebene \u00fcbertragen werden. Wenn man zu Patroni \u00fcber die REST API geht, gibt es eine Historie. \u00dcber die Historie kann man die Zeitstempel sehen, wann der Failer aufgetreten ist. Basierend darauf kann man Monitoring erstellen. Man kann die Historie betrachten, wie viele Ereignisse es gab. Wenn es mehr Ereignisse gibt, bedeutet das, dass der Auto-Failer stattgefunden hat. Man kann nachsehen. Oder unsere Automatisierung im Monitoring hat \u00fcberpr\u00fcft, dass alle Replikate vorhanden sind, es keine Verz\u00f6gerung gibt und alles gut ist. <\/p>\n<p><\/p>\n<p><em>Danke!<\/em><\/p>\n<p><\/p>\n<p><em>Vielen Dank f\u00fcr die gro\u00dfartige Geschichte! Wenn wir den DCS-Cluster irgendwo weit vom Postgres-Cluster verlegt haben, muss dieser Cluster dann auch regelm\u00e4\u00dfig gewartet werden? Welche Best Practices gibt es daf\u00fcr, dass bestimmte Teile des DCS-Clusters abgeschaltet werden, dass man etwas damit macht usw.? Wie funktioniert dabei die gesamte Struktur? Und wie macht man diese Dinge?<\/em><\/p>\n<p><\/p>\n<p>F\u00fcr ein Unternehmen musste eine Problemmatrix erstellt werden, was passiert, wenn eines oder mehrere Komponenten ausfallen. Anhand dieser Matrix durchgehen wir nacheinander alle Komponenten und erstellen Szenarien f\u00fcr den Fall, dass diese Komponenten ausfallen. F\u00fcr jedes Ausfallszenario kann es dann einen Aktionsplan zur Wiederherstellung geben. Und im Fall von DCS geh\u00f6rt das als Teil der Standardinfrastruktur dazu. Und der Administrator verwaltet dies, und wir verlassen uns bereits auf die Administratoren, die das verwalten und auf ihre F\u00e4higkeiten, es im Falle eines Ausfalls zu reparieren. Wenn der DCS gar nicht vorhanden ist, bauen wir ihn auf, aber wir \u00fcberwachen ihn dabei nicht speziell, weil wir nicht f\u00fcr die Infrastruktur verantwortlich sind, geben aber Empfehlungen, was und wie man monitoren sollte. <\/p>\n<p><\/p>\n<p><em>D. h. habe ich das richtig verstanden, dass man Patroni abschalten, den Failer deaktivieren und alles abstellen muss, bevor man etwas mit den Hosts macht?<\/em><\/p>\n<p><\/p>\n<p>Es h\u00e4ngt davon ab, wie viele Knoten wir im DCS-Cluster haben. Wenn es viele Knoten gibt und wir nur einen Knoten (eine Replik) au\u00dfer Betrieb nehmen, bleibt das Quorum im Cluster erhalten. Und Patroni bleibt funktionsf\u00e4hig. Und nichts wird ausgel\u00f6st. Wenn wir jedoch komplexe Operationen haben, die mehrere Knoten betreffen, deren Fehlen das Quorum gef\u00e4hrden k\u00f6nnte, dann ist es vielleicht sinnvoll, Patroni kurzzeitig zu pausieren. Daf\u00fcr gibt es den entsprechenden Befehl \u2013 patronictl pause, patronictl resume. Wir setzen einfach auf Pause, und das automatische Failover funktioniert in dieser Zeit nicht. Wir f\u00fchren Wartungsarbeiten am DCS-Cluster durch, setzen die Pause dann wieder auf und leben weiter.<\/p>\n<p><\/p>\n<p><em>Vielen Dank!<\/em><\/p>\n<p><\/p>\n<p><em>Vielen Dank f\u00fcr den Vortrag! Wie steht das Produktteam dazu, dass Daten verloren gehen k\u00f6nnen?<\/em> <\/p>\n<p><\/p>\n<p>Das Produktteam ist es egal, aber die Teamleiter sind besorgt. <\/p>\n<p><\/p>\n<p><em>Welche Garantien gibt es dort?<\/em><\/p>\n<p><\/p>\n<p>Mit Garantien ist es sehr schwierig. Es gibt einen Vortrag von Alexander Kukushkin \u201eWie man RPO und RTO berechnet\u201c, d. h. die Wiederherstellungszeit und wie viele Daten wir verlieren k\u00f6nnen. Ich denke, wir sollten diese Folien finden und sie uns ansehen. Soweit ich mich erinnere, gibt es dort konkrete Schritte, wie man diese Dinge berechnet. Wie viele Transaktionen k\u00f6nnen wir verlieren, wie viele Daten k\u00f6nnen wir verlieren. Als M\u00f6glichkeit k\u00f6nnten wir die synchrone Replikation auf Patroni-Ebene verwenden, aber das ist ein zweischneidiges Schwert: entweder haben wir Datensicherheit oder wir verlieren an Geschwindigkeit. Es gibt zwar synchrone Replikation, aber die garantiert auch keinen 100%-igen Schutz vor Datenverlust.<\/p>\n<p><\/p>\n<p><em>Alexey, danke f\u00fcr den tollen Vortrag! Gibt es Erfahrungen mit der Verwendung von Patroni f\u00fcr den nullten Schutzlevel? Das hei\u00dft, in Verbindung mit dem synchronen Standby? Das ist die erste Frage. Und die zweite Frage. Sie haben verschiedene L\u00f6sungen verwendet. Wir haben Repmgr verwendet, aber ohne automatisches Failover und planen jetzt, das automatische Failover zu aktivieren. Wir betrachten Patroni als alternative L\u00f6sung. Was k\u00f6nnen Sie im Vergleich zu Repmgr als Vorteile nennen?<\/em><\/p>\n<p><\/p>\n<p>Die erste Frage war zur synchronen Replikation. Keiner von uns verwendet synchrone Replikation, weil alle Angst haben (es verwenden bereits mehrere Kunden, Probleme mit der Leistung wurden grunds\u00e4tzlich nicht festgestellt \u2014 <em>Anmerkung des Vortragenden<\/em>). Aber wir haben f\u00fcr uns die Regel aufgestellt, dass es im Cluster der synchronen Replikation mindestens drei Knoten geben muss, denn wenn wir zwei Knoten haben und einer der Master oder Repliken ausf\u00e4llt, geht Patroni dazu \u00fcber, diesen Knoten in den Standalone-Modus zu versetzen, damit die Anwendung weiterhin arbeiten kann. In diesem Fall besteht das Risiko eines Datenverlusts.<\/p>\n<p><\/p>\n<p>Zum zweiten Punkt haben wir Repmgr verwendet und verwenden es aus historischen Gr\u00fcnden immer noch bei einigen Kunden. Was kann man dazu sagen? In Patroni ist die Auto-Failover-Funktion standardm\u00e4\u00dfig integriert, bei Repmgr ist sie bereits eine zus\u00e4tzliche Funktion, die aktiviert werden muss. Es ist notwendig, den Repmgr-Daemon auf jedem Knoten zu starten, und dann k\u00f6nnen wir das Auto-Failover einrichten. <\/p>\n<p><\/p>\n<p>Repmgr \u00fcberpr\u00fcft, welche Postgres-Knoten aktiv sind. Die Repmgr-Prozesse \u00fcberpr\u00fcfen die Existenz miteinander, was nicht sehr effizient ist, da es komplexe F\u00e4lle der Netzwerk-Isolation geben kann, in denen ein gro\u00dfer Repmgr-Cluster sich in mehrere kleine zerlegen und weiterarbeiten kann. Ich habe lange nicht mehr auf Repmgr geachtet, vielleicht wurde das behoben... vielleicht aber auch nicht. Aber die Auslagerung von Informationen \u00fcber den Zustand des Clusters in DCS, wie es Stolon und Patroni machen, ist die lebensf\u00e4higste Option. <\/p>\n<p><\/p>\n<p><em>Alexej, ich habe eine Frage, vielleicht eine unerfahrene. In einem der ersten DCS-Beispiele hast du es von einer lokalen Maschine auf einen Remote-Knoten ausgelagert. Wir verstehen, dass ein Netzwerk eine eigene Dynamik hat. Was passiert, wenn aus irgendeinem Grund der DCS-Cluster nicht mehr verf\u00fcgbar ist? Ich m\u00f6chte die Gr\u00fcnde nicht ansprechen; es k\u00f6nnte viele Ursachen geben: von fehlerhaften Netzwerktechnikern bis hin zu echten Problemen.<\/em> <\/p>\n<p><\/p>\n<p>Ich habe das nicht laut ausgesprochen, aber der DCS-Cluster sollte ebenfalls ausfallsicher sein, d. h. eine ungerade Anzahl von Knoten haben, damit ein Quorum gebildet werden kann. Was passiert, wenn der DCS-Cluster nicht mehr verf\u00fcgbar ist oder kein Quorum gebildet werden kann, also bei einem Netzwerk-Split oder einem Knotenfehler? In diesem Fall wechselt der Patroni-Cluster in den Nur-Lesen-Modus. Der Patroni-Cluster kann den Zustand des Clusters und was zu tun ist, nicht bestimmen. Er kann nicht mit DCS kommunizieren und den neuen Zustand des Clusters nicht speichern, weshalb der gesamte Cluster in den Nur-Lesen-Modus wechselt. Er wartet entweder auf manuelle Eingriffe des Operators oder darauf, dass DCS wiederhergestellt wird.<\/p>\n<p><\/p>\n<p><em>Gro\u00df gesagt, wird DCS f\u00fcr uns zu einem Dienst, der ebenso wichtig ist wie die Datenbank selbst?<\/em><\/p>\n<p><\/p>\n<p>Ja, ja. In sehr vielen modernen Unternehmen ist Service Discovery ein unverzichtbarer Bestandteil der Infrastruktur. Es wird sogar fr\u00fcher implementiert, als eine Datenbank in der Infrastruktur vorhanden ist. Um es vereinfacht zu sagen: Die Infrastruktur wurde gestartet, das Rechenzentrum wurde eingerichtet, und sofort haben wir Service Discovery. Wenn es sich um Consul handelt, kann auch DNS darauf aufgebaut werden. Wenn es sich um Etcd handelt, kann ein Teil des Kubernetes-Clusters sein, in dem bereits alles andere bereitgestellt wird. Ich denke, dass Service Discovery bereits ein integraler Bestandteil moderner Infrastrukturen ist. Und man denkt viel fr\u00fcher dar\u00fcber nach als \u00fcber Datenbanken. <\/p>\n<p><\/p>\n<p><em>Danke!<\/em><\/p>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/512768\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c Patroni \u2014 \u044d\u0442\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435 High Availability \u0434\u043b\u044f PostgreSQL. \u041d\u043e Patroni \u2014 \u044d\u0442\u043e \u043b\u0438\u0448\u044c template, \u0430 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 (\u0447\u0442\u043e, \u0432 \u043e\u0431\u0449\u0435\u043c, \u0438 \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438). \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0432 Patroni \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u043b\u0430\u0431\u0435, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u044d\u0442\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0438 \u043a\u0430\u043a \u043e\u043d \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0448\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0440\u0430\u0437\u0432\u0430\u043b\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0442\u0435\u0440. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":90104,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-90103","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\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\/patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\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\udd47Patroni Failure Stories or How to crash your PostgreSQL cluster. \u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u041b\u0435\u0441\u043e\u0432\u0441\u043a\u0438\u0439 | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij\" \/>\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-07-29T11:42:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-29T11:42:32+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\udd47Patroni-Fehlergeschichten oder Wie man seinen PostgreSQL-Cluster zum Absturz bringt. Alexey Lesovsky | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij","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\udd47Patroni Failure Stories or How to crash your PostgreSQL cluster. \u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u041b\u0435\u0441\u043e\u0432\u0441\u043a\u0438\u0439 | ProHoster","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij","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-07-29T11:42:32+00:00","article:modified_time":"2020-07-29T11:42:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"90103","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 12:58:48","updated":"2026-02-09 16:50:35","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/90103","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=90103"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/90103\/revisions"}],"predecessor-version":[{"id":158759,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/90103\/revisions\/158759"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/90104"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=90103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=90103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=90103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}