{"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\/es\/blog\/administrirovanie\/patroni-failure-stories-or-how-to-crash-your-postgresql-cluster-aleksej-lesovskij","title":{"rendered":"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/6404cba13214f499d1f347cca0aacbe7.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El objetivo principal de Patroni es garantizar la alta disponibilidad para PostgreSQL. Pero Patroni es solo una plantilla, no una herramienta lista para usar (como se menciona en la documentaci\u00f3n). A primera vista, al configurar Patroni en un laboratorio de pruebas, se puede ver lo magn\u00edfico que es y lo f\u00e1cil que maneja nuestros intentos de hacer fallar el cl\u00faster. Sin embargo, en la pr\u00e1ctica, en un entorno de producci\u00f3n, no siempre todo ocurre de manera tan hermosa y elegante como en el laboratorio de pruebas.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ff445e6d76a2ad46a232b705e104446f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Perm\u00edtanme contarles un poco sobre m\u00ed. Comenc\u00e9 como administrador de sistemas. Trabaj\u00e9 en desarrollo web. Desde 2014 trabajo en Data Egret. La empresa se dedica a la consultor\u00eda en el \u00e1mbito de Postgres. Atendemos espec\u00edficamente a Postgres y trabajamos con \u00e9l todos los d\u00edas, por lo que tenemos una diversa experiencia relacionada con su operaci\u00f3n. <\/p>\n<p><\/p>\n<p>A finales de 2018 comenzamos a utilizar Patroni poco a poco. Y acumulamos cierta experiencia. Lo diagnosticamos, lo ajustamos y llegamos a nuestras mejores pr\u00e1cticas. En esta presentaci\u00f3n hablar\u00e9 de ellas.<\/p>\n<p><\/p>\n<p>Adem\u00e1s de Postgres, me encanta Linux. Disfruto trastear e investigar, me gusta compilar n\u00facleos. Me fascinan la virtualizaci\u00f3n, los contenedores, Docker y Kubernetes. Todo esto me interesa, ya que refleja los viejos h\u00e1bitos de administrador. Me gusta entender los sistemas de monitoreo. Y disfruto de las cuestiones de administraci\u00f3n de Postgres, es decir, replicaci\u00f3n, copias de seguridad. En mi tiempo libre, programo en Go. No soy ingeniero de software, solo programo para m\u00ed, y me da placer. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/02cfd9293af5a8410c91e39afe2c75e6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Creo que muchos de ustedes saben que Postgres no tiene HA (alta disponibilidad) de forma nativa. Para obtener HA, es necesario instalar algo, configurarlo, esforzarse y conseguirlo. <\/li>\n<li>Hay varias herramientas, y Patroni es una de ellas, que resuelve HA de manera bastante efectiva y muy bien. Pero al instalar todo esto en el laboratorio de pruebas y ponerlo en marcha, podemos ver que funciona, podemos reproducir ciertos problemas y observar c\u00f3mo Patroni los maneja. Y veremos que todo funciona a la perfecci\u00f3n. <\/li>\n<li>Pero en la pr\u00e1ctica hemos enfrentado diferentes problemas. Y sobre esos problemas hablar\u00e9.<\/li>\n<li>Les contar\u00e9 c\u00f3mo lo diagnosticamos, qu\u00e9 ajustes hicimos - si nos ayud\u00f3 o no. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/7126b45b40dd08521e80a3c150382bec.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>No voy a contar c\u00f3mo instalar Patroni, porque se puede buscar en internet, se pueden ver los archivos de configuraci\u00f3n para entender c\u00f3mo se inicia y se configura todo. Se puede entender los esquemas y arquitecturas encontrando informaci\u00f3n al respecto en l\u00ednea. <\/li>\n<li>No voy a hablar de la experiencia de otros. Solo hablar\u00e9 de los problemas que nosotros enfrentamos. <\/li>\n<li>Y no hablar\u00e9 de problemas que est\u00e1n fuera de Patroni y PostgreSQL. Por ejemplo, problemas relacionados con el balanceo de carga, cuando nuestro cl\u00faster se colaps\u00f3; de eso no hablar\u00e9. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/3f8d179e7c78ce83e8842ef5c72fe30d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y un peque\u00f1o aviso antes de empezar nuestra presentaci\u00f3n. <\/p>\n<p><\/p>\n<p>Todos estos problemas con los que nos encontramos ocurrieron durante los primeros 6-7-8 meses de operaci\u00f3n. Con el tiempo llegamos a nuestras mejores pr\u00e1cticas internas y los problemas desaparecieron. Por eso, la presentaci\u00f3n fue programada hace aproximadamente medio a\u00f1o, cuando todo estaba fresco en mi mente y lo recordaba perfectamente. <\/p>\n<p><\/p>\n<p>Durante la preparaci\u00f3n de la presentaci\u00f3n, revis\u00e9 antiguos informes post-mortem y revis\u00e9 los registros. Y algunas partes de los detalles podr\u00edan haberse olvidado, o podr\u00edan no haber sido completamente investigadas durante el an\u00e1lisis de los problemas, por lo que en algunos momentos puede parecer que los problemas no fueron completamente explorados o que falta informaci\u00f3n. Por eso, les pido disculpas por este aspecto. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/30d414284a41fcbc3bf417c9da28ca52.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfQu\u00e9 es Patroni?<\/p>\n<p><\/p>\n<ul>\n<li>Es una plantilla para construir HA. As\u00ed est\u00e1 escrito en la documentaci\u00f3n. Y desde mi punto de vista, es una aclaraci\u00f3n muy correcta. Patroni no es una soluci\u00f3n m\u00e1gica que resolver\u00e1 todos tus problemas, es decir, se necesita hacer un esfuerzo para que empiece a funcionar y sea de utilidad. <\/li>\n<li>Es un servicio de agente que se instala en cada servicio con una base de datos, que act\u00faa como una especie de sistema init para tu Postgres. Arranca Postgres, lo detiene, lo reinicia, cambia la configuraci\u00f3n y la topolog\u00eda de tu cl\u00faster. <\/li>\n<li>Por lo tanto, para almacenar el estado del cl\u00faster, su representaci\u00f3n actual, c\u00f3mo se ve, se necesita alg\u00fan tipo de almacenamiento. Y desde este punto de vista, Patroni opt\u00f3 por almacenar el estado en un sistema externo. Es un sistema de almacenamiento de configuraci\u00f3n distribuido. Puede ser Etcd, Consul, ZooKeeper, o Etcd de Kubernetes, es decir, alguna de estas opciones. <\/li>\n<li>Una de las caracter\u00edsticas de Patroni es que el autofailover lo obtienes listo para usar, simplemente configur\u00e1ndolo. Si comparamos con Repmgr, el failover all\u00ed viene incluido. Con Repmgr obtenemos switchover, pero si queremos un autofailover, necesitamos configurarlo adicionalmente. En Patroni, el autofailover ya est\u00e1 incluido por defecto.<\/li>\n<li>Y hay muchas otras cosas. Por ejemplo, el mantenimiento de configuraciones, la adici\u00f3n de nuevas r\u00e9plicas, copias de seguridad, etc. Pero eso est\u00e1 fuera del alcance de esta presentaci\u00f3n, de eso no hablar\u00e9. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fed0f1ce931df99ca76ae1116f8098cc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y un peque\u00f1o resumen es que la principal tarea de Patroni es realizar el autofailover de manera adecuada y confiable, de modo que nuestro cl\u00faster siga funcionando y la aplicaci\u00f3n no note cambios en la topolog\u00eda del cl\u00faster. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fac52620957efa47ced330e7cc8084e0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pero cuando empezamos a usar Patroni, nuestro sistema se vuelve un poco m\u00e1s complicado. Si antes ten\u00edamos Postgres, al usar Patroni tenemos a Patroni mismo, obtenemos DCS, donde se almacena el estado. Y todo esto debe funcionar de alguna manera. As\u00ed que, \u00bfqu\u00e9 puede fallar?<\/p>\n<p><\/p>\n<p>Puede fallar:<\/p>\n<p><\/p>\n<ul>\n<li>Puede fallar Postgres. Puede ser un maestro o una r\u00e9plica, algo de ellos puede fallar. <\/li>\n<li>Puede fallar el propio Patroni. <\/li>\n<li>Puede fallar el DCS, donde se almacena el estado.<\/li>\n<li>Y puede fallar la red. <\/li>\n<\/ul>\n<p><\/p>\n<p>Todos estos aspectos los estar\u00e9 tratando en la presentaci\u00f3n. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/1aeaf46d37bf1935b514b0581e0dbd0b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voy a considerar los casos seg\u00fan se vayan complicando, no desde el punto de vista de que el caso involucra muchos componentes. Sino desde el punto de vista de sensaciones subjetivas, que este caso fue complicado para m\u00ed, que fue dif\u00edcil de desglosar... y al contrario, que alg\u00fan caso fue f\u00e1cil y fue f\u00e1cil de desglosar. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/65b0c98bf2284610e955ced5eb998f39.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y el primer caso es el m\u00e1s simple. Es aquel en el que tomamos un cl\u00faster de bases de datos y en este mismo cl\u00faster desplegamos nuestro almac\u00e9n DCS. Este es un error muy com\u00fan. Es un error de construcci\u00f3n arquitect\u00f3nica, es decir, la combinaci\u00f3n de diferentes componentes en un mismo lugar. <\/p>\n<p><\/p>\n<p>Entonces, ocurri\u00f3 el failover, vamos a investigar qu\u00e9 sucedi\u00f3. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/244b69d623fe2205c2d9ed2aa4620067.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y aqu\u00ed nos interesa saber cu\u00e1ndo ocurri\u00f3 el failover. Es decir, nos interesa este momento en el tiempo cuando ocurri\u00f3 el cambio de estado del cl\u00faster. <\/p>\n<p><\/p>\n<p>Pero el failover no siempre es inmediato, es decir, no ocupa una unidad de tiempo, puede extenderse. Puede ser prolongado en el tiempo.<\/p>\n<p><\/p>\n<p>Por lo tanto, tiene un tiempo de inicio y un tiempo de finalizaci\u00f3n, es decir, es un evento prolongado. Dividimos todos los eventos en tres intervalos: tenemos el tiempo antes del failover, durante el failover y despu\u00e9s del failover. Es decir, consideramos todos los eventos en esta l\u00ednea de tiempo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a0ed61afe55d1a157147e0d80b17e5d1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y lo primero que hacemos cuando ocurre el failover es buscar la causa, qu\u00e9 sucedi\u00f3, qu\u00e9 provoc\u00f3 que se produjera el failover. <\/p>\n<p><\/p>\n<p>Si miramos los registros, ser\u00e1n los registros cl\u00e1sicos de Patroni. En ellos nos informa que el servidor se ha convertido en el maestro y que el rol de maestro ha pasado a este nodo. Aqu\u00ed est\u00e1 resaltado. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/9998c69f7d0d4358b277f4e0e7b4350f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Luego, necesitamos entender por qu\u00e9 ocurri\u00f3 el failover, es decir, qu\u00e9 eventos ocurrieron que hicieron que el rol de maestro se trasladara de un nodo a otro. En este caso, es muy sencillo. Tenemos un error de interacci\u00f3n con el sistema de almacenamiento. El maestro se dio cuenta de que no pod\u00eda trabajar con DCS, es decir, surgi\u00f3 alg\u00fan problema de comunicaci\u00f3n. Y dice que ya no puede ser m\u00e1s maestro y renuncia a sus funciones. Esta l\u00ednea \"demoted self\" habla precisamente de eso. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/4a8eca27689546b4b0fc3c666a3c37c4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si vemos los eventos que precedieron al failover, podemos ver las causas que generaron problemas para la continuaci\u00f3n del funcionamiento del maestro. <\/p>\n<p><\/p>\n<p>Si consultamos los registros de Patroni, veremos que tenemos una gran cantidad de errores, timeouts, es decir, el agente de Patroni no puede trabajar con DCS. En este caso, se trata del agente Consul, con el cual se comunica a trav\u00e9s del puerto 8500. <\/p>\n<p><\/p>\n<p>Y el problema radica en que Patroni y la base de datos se ejecutan en el mismo host. Y en este mismo nodo se ejecutaron servidores Consul. Al crear carga en el servidor, generamos problemas tambi\u00e9n para el <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/es\/server\/\"   title=\"servidores\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1515\">servidores<\/a> Consul. No pudieron comunicarse correctamente. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/0d8dba6641809560e6b32825d481e30b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Despu\u00e9s de un tiempo, cuando la carga disminuy\u00f3, nuestro Patroni pudo comunicarse nuevamente con los agentes. La operaci\u00f3n normal se reanud\u00f3. Y el mismo servidor Pgdb-2 volvi\u00f3 a ser el maestro. Es decir, hubo un peque\u00f1o flip, debido al cual el nodo renunci\u00f3 a su rol de maestro y luego lo asumi\u00f3 de nuevo, es decir, todo volvi\u00f3 a la normalidad. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/131b93e0bd83099e1b99b53742419e13.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y esto puede considerarse como un falso disparo, o se puede considerar que Patroni hizo todo correctamente. Es decir, entendi\u00f3 que no pod\u00eda mantener el estado del cl\u00faster y renunci\u00f3 a su rol.<\/p>\n<p><\/p>\n<p>Y aqu\u00ed surgi\u00f3 el problema porque los servidores Consul est\u00e1n en el mismo hardware que las bases de datos. Por lo tanto, cualquier carga: ya sea en discos o en procesadores, tambi\u00e9n afecta la interacci\u00f3n con el cl\u00faster de Consul.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/142c7cf839c8da078451f7ba9d5499e5.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Decidimos que esto no deber\u00eda coexistir, as\u00ed que separamos un cl\u00faster para Consul. Patroni ya funcionaba con un Consul separado, es decir, hab\u00eda un cl\u00faster de Postgres y un cl\u00faster de Consul por separado. Esta es la instrucci\u00f3n b\u00e1sica sobre c\u00f3mo distribuir y mantener todas estas cosas para que no vivan juntas. <\/p>\n<p><\/p>\n<p>Como opci\u00f3n, se pueden ajustar los par\u00e1metros ttl, loop_wait, retry_timeout, es decir, intentar sobrevivir a estos picos de carga a corto plazo al aumentar estos par\u00e1metros. Pero esta no es la mejor opci\u00f3n, porque esta carga puede ser prolongada. Y simplemente superaremos los l\u00edmites de estos par\u00e1metros. Y esto puede no ser de gran ayuda. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/c51f35dcd88b1c792acec231c0c6c66c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El primer problema, como entendieron, es simple. Juntamos DCS con la base de datos y obtuvimos un problema. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/cc2a98d9790441577fb4080406cbc53f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El segundo problema es similar al primero. Es similar en que de nuevo tenemos problemas de interacci\u00f3n con el sistema DCS.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/e5c01b105adca48cc620085db8dd2d2b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si miramos los registros, veremos que nuevamente hay un error de comunicaci\u00f3n. Y Patroni dice que no puede interactuar con DCS, por lo que el maestro actual pasa a modo r\u00e9plica.<\/p>\n<p><\/p>\n<p>El viejo maestro se convierte en r\u00e9plica, aqu\u00ed Patroni act\u00faa como se espera. Ejecuta pg_rewind para retroceder el registro de transacciones y luego conectarse al nuevo maestro, y ya alcanzar al nuevo maestro. Aqu\u00ed Patroni act\u00faa como se supone que debe. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/29255f4790abb15b64dbf9ee0b41c7fc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqu\u00ed debemos encontrar el lugar que precedi\u00f3 al failure, es decir, los errores que causaron por qu\u00e9 ocurri\u00f3 el failure. En este sentido, es bastante conveniente trabajar con los registros de Patroni. Escribe los mismos mensajes en intervalos determinados. Y si comenzamos a recorrer estos registros r\u00e1pidamente, veremos que han cambiado, lo que significa que han comenzado algunos problemas. Volvemos r\u00e1pidamente a ese lugar y vemos qu\u00e9 est\u00e1 sucediendo. <\/p>\n<p><\/p>\n<p>Y en una situaci\u00f3n normal, los registros se ven aproximadamente as\u00ed. Se verifica el propietario del bloqueo. Y si el propietario, digamos, cambi\u00f3, pueden ocurrir ciertos eventos que Patroni debe manejar. Pero en este caso, todo est\u00e1 bien. Buscamos el lugar cuando comenzaron los errores. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f48ebd22a405f5b2900621451c68f543.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Al desplazarnos hasta el punto donde comenzaron a aparecer los errores, vemos que se produjo un failover autom\u00e1tico. Y dado que nuestros errores estaban relacionados con la interacci\u00f3n con DCS y en nuestro caso usamos Consul, tambi\u00e9n revisamos los registros de Consul para ver qu\u00e9 sucedi\u00f3 all\u00ed. <\/p>\n<p><\/p>\n<p>Al comparar aproximadamente el tiempo del failover con el tiempo en los registros de Consul, vemos que nuestros vecinos en el cl\u00faster de Consul comenzaron a dudar de la existencia de otros participantes en el cl\u00faster de Consul.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/63b02ac5b4f5a34a2822f1eee2b1f2f8.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y si tambi\u00e9n miramos los registros de otros agentes de Consul, tambi\u00e9n se puede observar que hay alg\u00fan colapso de red ocurriendo. Y todos los participantes del cl\u00faster de Consul dudan de la existencia de los dem\u00e1s. Esto fue un catalizador para el failover. <\/p>\n<p><\/p>\n<p>Si observamos lo que sucedi\u00f3 antes de estos errores, podemos ver que hay todo tipo de errores, como deadline, RPC fallido, es decir, claramente hay alg\u00fan problema en la interacci\u00f3n entre los participantes del cl\u00faster de Consul. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b15c912f2afb49d9d85e7bb9361ce449.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La respuesta m\u00e1s sencilla es reparar la red. Pero desde mi posici\u00f3n, es f\u00e1cil decirlo. Sin embargo, las circunstancias son tales que el cliente no siempre podr\u00e1 permitirse reparar la red. Puede vivir en un centro de datos y no tener la capacidad de reparar la red o influir en el equipo. Por lo tanto, se necesitan otras opciones. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/1dbdb66233acc3bc321a30a1c5fe14f9.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Existen opciones:<\/p>\n<p><\/p>\n<ul>\n<li>La opci\u00f3n m\u00e1s sencilla, que creo que est\u00e1 incluso escrita en la documentaci\u00f3n, es desactivar las comprobaciones de Consul, es decir, simplemente pasar un arreglo vac\u00edo. Y le decimos al agente de Consul que no use ninguna verificaci\u00f3n. Gracias a estas verificaciones, podemos ignorar estas tormentas de red y no iniciar un failover. <\/li>\n<li>Otra opci\u00f3n es volver a verificar el raft_multiplier. Este es un par\u00e1metro del servidor Consul. Por defecto, se establece en un valor de 5. Este valor es recomendado por la documentaci\u00f3n para entornos de staging. En esencia, afecta la frecuencia de intercambio de mensajes entre los participantes de la red de Consul. En realidad, este par\u00e1metro influye en la velocidad de la comunicaci\u00f3n auxiliar entre los participantes del cl\u00faster de Consul. Y para producci\u00f3n, ya se recomienda reducirlo para que los nodos intercambien mensajes con m\u00e1s frecuencia. <\/li>\n<li>Otra opci\u00f3n que hemos comenzado a utilizar es aumentar la prioridad de los procesos de Consul entre otros procesos para el planificador de procesos del sistema operativo. Hay un par\u00e1metro llamado \u00abnice\u00bb, que define precisamente la prioridad de los procesos que es considerada por el planificador del SO al programar. Hemos reducido el valor de nice para los agentes de Consul, es decir, hemos aumentado la prioridad para que el sistema operativo proporcione m\u00e1s tiempo a los procesos de Consul para trabajar y ejecutar su c\u00f3digo. En nuestro caso, esto resolvi\u00f3 el problema. <\/li>\n<li>Otra opci\u00f3n es no usar Consul. Tengo un amigo que es un gran defensor de Etcd. Y discutimos regularmente sobre qu\u00e9 es mejor, Etcd o Consul. Pero en t\u00e9rminos de cu\u00e1l es mejor, normalmente coincidimos en que Consul tiene un agente que debe estar en funcionamiento en cada nodo con la base de datos. Es decir, la interacci\u00f3n de Patroni con el cl\u00faster de Consul se realiza a trav\u00e9s de este agente. Y este agente se convierte en un cuello de botella. Si algo le sucede al agente, Patroni ya no puede trabajar con el cl\u00faster de Consul. Esto es un problema. En el caso de Etcd, no hay ning\u00fan agente. Patroni puede trabajar directamente con la lista de servidores de Etcd y comunicarse con ellos. En este sentido, si en su empresa utilizan Etcd, probablemente sea una mejor opci\u00f3n que Consul. Pero para nuestros clientes siempre estamos limitados por lo que el cliente ha elegido y utiliza. Y en su mayor\u00eda, Consul est\u00e1 presente en todos los clientes. <\/li>\n<li>Y el \u00faltimo punto es revisar los valores de los par\u00e1metros. Podemos aumentar estos par\u00e1metros con la esperanza de que nuestros problemas de red transitorios sean breves y no entren en el intervalo de estos par\u00e1metros. De esta manera, podemos reducir la agresividad de Patroni en la ejecuci\u00f3n del failover autom\u00e1tico si surgen problemas de red.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f0043050da20f6368dabf66ec9a4eade.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Creo que muchos que utilizan Patroni est\u00e1n familiarizados con este comando. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/9f78f59dab166e47ac78436802156d04.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Este comando muestra el estado actual del cl\u00faster. Y a primera vista, esta imagen puede parecer normal. Tenemos un maestro, tenemos una r\u00e9plica, no hay retraso en la replicaci\u00f3n. Pero esta imagen es normal solo hasta que sabemos que en este cl\u00faster deber\u00edan haber tres nodos, no dos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a39c891f8620ba210b6bce0727e0fa8b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Por lo tanto, ocurri\u00f3 un autofailover. Y despu\u00e9s de este autofailover, nuestra r\u00e9plica desapareci\u00f3. Necesitamos averiguar por qu\u00e9 desapareci\u00f3 y recuperarla. Y de nuevo, revisamos los registros para ver por qu\u00e9 ocurri\u00f3 el autofailover.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/e6e67d46cb20c8d7e58c7505157f68e1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En este caso, la segunda r\u00e9plica se convirti\u00f3 en maestro. Todo est\u00e1 bien aqu\u00ed. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b86ccea68b0c6013a23bbd2804e48320.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y necesitamos observar la r\u00e9plica que se desconect\u00f3 y que no est\u00e1 en el cl\u00faster. Abrimos los registros de Patroni y vemos que surgi\u00f3 un problema en el proceso de conexi\u00f3n al cl\u00faster en la fase de pg_rewind. Para conectarse al cl\u00faster, es necesario retroceder el registro de transacciones, solicitar el registro de transacciones necesario del maestro y alcanzarlo. <\/p>\n<p><\/p>\n<p>En este caso, no tenemos el registro de transacciones y la r\u00e9plica no puede iniciarse. Por lo tanto, detenemos Postgres con un error. Y es por eso que no est\u00e1 en el cl\u00faster. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/dadbd44b766674b719d85781ef7f0caa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Es necesario entender por qu\u00e9 no est\u00e1 en el cl\u00faster y por qu\u00e9 no hab\u00eda registros. Vamos al nuevo maestro y vemos qu\u00e9 hay en sus registros. Resulta que cuando se hizo el pg_rewind, ocurri\u00f3 un checkpoint. Y parte de los antiguos registros de transacciones simplemente fue renombrada. Cuando el antiguo maestro intent\u00f3 conectarse al nuevo maestro y solicitar esos registros, ya hab\u00edan sido renombrados; simplemente no estaban.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f2d5c37324f9436b2bdad1290612d86f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Compar\u00e9 las marcas de tiempo cuando ocurrieron estos eventos. Y la diferencia es de apenas 150 milisegundos, es decir, el checkpoint se complet\u00f3 en 369 milisegundos y los segmentos WAL fueron renombrados. Y apenas 517 milisegundos despu\u00e9s, se inici\u00f3 el rewind en la antigua r\u00e9plica. Es decir, se necesit\u00f3 literalmente 150 milisegundos para que la r\u00e9plica no pudiera conectarse y funcionar. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/99dd80deb8466bfc3aff568456e07102.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfCu\u00e1les son las opciones?<\/p>\n<p><\/p>\n<p>Inicialmente utilizamos slots de replicaci\u00f3n. Nos parec\u00eda que esto era bueno. Sin embargo, en la primera etapa de uso, desactivamos los slots. Pensamos que, si los slots acumulaban muchos segmentos WAL, podr\u00edamos caer el maestro. Por un tiempo, lidiamos sin slots. Y luego entendimos que los slots son necesarios, as\u00ed que los recuperamos. <\/p>\n<p><\/p>\n<p>Pero aqu\u00ed hay un problema, que cuando el maestro cambia a la r\u00e9plica, elimina los slots y junto con los slots elimina los segmentos WAL. Y para evitar que este problema ocurra, decidimos aumentar el par\u00e1metro wal_keep_segments. Por defecto son 8 segmentos. Lo subimos a 1,000 y vimos cu\u00e1nto espacio libre ten\u00edamos. Y donamos 16 gigabytes para wal_keep_segments. Es decir, al hacer el cambio, siempre tenemos en todos los nodos un margen de 16 gigabytes de registros de transacciones.<\/p>\n<p><\/p>\n<p>Y adem\u00e1s, esto es relevante para tareas de mantenimiento prolongadas. Supongamos que necesitamos actualizar una de las r\u00e9plicas. Y queremos apagarla. Necesitamos actualizar el software, tal vez el sistema operativo, o algo m\u00e1s. Y cuando apagamos la r\u00e9plica, tambi\u00e9n se elimina el slot de esa r\u00e9plica. Y si usamos un wal_keep_segments peque\u00f1o, al estar la r\u00e9plica ausente durante un largo tiempo, los registros de transacciones se reproducir\u00e1n. Reiniciaremos la r\u00e9plica, pedir\u00e1 esos registros de transacciones donde se detuvo, pero en el maestro puede que no existan. Y la r\u00e9plica tampoco podr\u00e1 conectarse. Por eso mantenemos un gran margen de registros.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. 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=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/63e70f0b098567f3a6d4fd66a0c293bb.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tenemos una base de producci\u00f3n. All\u00ed ya est\u00e1n funcionando proyectos. <\/p>\n<p><\/p>\n<p>Ha ocurrido un failover. Entramos y revisamos: todo est\u00e1 bien, las r\u00e9plicas est\u00e1n en su lugar, no hay retraso en la replicaci\u00f3n. No hay errores en los registros, todo est\u00e1 en orden. <\/p>\n<p><\/p>\n<p>El equipo de producto dice que deber\u00edan haber algunos datos, pero los vemos en una fuente, y en la base no los vemos. Y necesitamos entender qu\u00e9 ocurri\u00f3 con ellos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/568ca9aa31680d5e0c9d4ed9693b14e6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Est\u00e1 claro que pg_rewind los ha sobrescrito. Nos dimos cuenta de esto de inmediato, pero fuimos a investigar qu\u00e9 hab\u00eda pasado. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a8fee389201d96e81761cd276c5265c3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En los logs siempre podemos encontrar cu\u00e1ndo ocurri\u00f3 el failover, qui\u00e9n se convirti\u00f3 en maestro y podemos determinar qui\u00e9n era el antiguo maestro y cu\u00e1ndo quiso convertirse en r\u00e9plica, es decir, necesitamos esos logs para averiguar el volumen de registros de transacciones que se perdi\u00f3.<\/p>\n<p><\/p>\n<p>Nuestro viejo maestro se reinici\u00f3. Y en el arranque autom\u00e1tico estaba configurado Patroni. Patroni se inici\u00f3. Luego, lanz\u00f3 Postgres. M\u00e1s bien, antes de iniciar Postgres y antes de convertirlo en r\u00e9plica, Patroni ejecut\u00f3 el proceso pg_rewind. Por lo tanto, borr\u00f3 parte de los registros de transacciones, descarg\u00f3 los nuevos y se conect\u00f3. Aqu\u00ed, Patroni funcion\u00f3 de maravilla, es decir, como se esperaba. Nuestro cl\u00faster se recuper\u00f3. Ten\u00edamos 3 nodos, despu\u00e9s del failover 3 nodos - todo genial. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b747a24f53e20ed098c2dc0afc79bead.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hemos perdido parte de los datos. Y necesitamos entender cu\u00e1nto hemos perdido. Estamos buscando el momento exacto en el que ocurri\u00f3 el rewind. Podemos encontrar esto a trav\u00e9s de registros en el log. Se inici\u00f3 el rewind, hizo algo y finaliz\u00f3.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/5b7bacffb52e3ccd529a3a734c441295.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Necesitamos encontrar la posici\u00f3n en el log de transacciones donde se detuvo el antiguo maestro. En este caso, este es el marcador. Y necesitamos un segundo marcador, es decir, la distancia que difiere el antiguo maestro del nuevo. <\/p>\n<p><\/p>\n<p>Tomamos la diferencia pg_wal_lsn_diff habitual y comparamos estos dos marcadores. En este caso, obtenemos 17 megabytes. Cada uno decide si esto es mucho o poco. Porque para algunos 17 megabytes es poco, para otros es mucho e inaceptable. Aqu\u00ed cada uno determina individualmente de acuerdo con las necesidades del negocio. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/55335fce85961e159459c38300a0ad12.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfPero qu\u00e9 hemos descubierto para nosotros? <\/p>\n<p><\/p>\n<p>En primer lugar, debemos decidir si siempre necesitamos el autoarranque de Patroni tras un reinicio del sistema. A menudo sucede que debemos acceder al antiguo maestro, ver cu\u00e1n lejos ha llegado. Posiblemente inspeccionar los segmentos del log de transacciones, ver qu\u00e9 hay all\u00ed. Y entender si podemos perder estos datos o si necesitamos arrancar el antiguo maestro en modo independiente para recuperar estos datos. <\/p>\n<p><\/p>\n<p>Y solo despu\u00e9s de esto debemos tomar decisiones sobre si podemos descartar estos datos o si podemos restaurarlos, conectando este nodo como r\u00e9plica en nuestro cl\u00faster.<\/p>\n<p><\/p>\n<p>Adem\u00e1s, hay un par\u00e1metro llamado 'maximum_lag_on_failover'. Por defecto, si no me equivoco, este par\u00e1metro tiene un valor de 1 megabyte. <\/p>\n<p><\/p>\n<p>\u00bfC\u00f3mo funciona? Si nuestra r\u00e9plica tiene un retraso de 1 megabyte de datos por el lag de replicaci\u00f3n, esta r\u00e9plica no participa en las elecciones. Y si ocurre un failover, Patroni verifica qu\u00e9 r\u00e9plicas est\u00e1n retrasadas. Si est\u00e1n atrasadas en una gran cantidad de logs de transacciones, no pueden convertirse en maestro. Esta es una muy buena funci\u00f3n de protecci\u00f3n que evita la p\u00e9rdida de muchos datos. <\/p>\n<p><\/p>\n<p>Pero aqu\u00ed hay un problema: el lag de replicaci\u00f3n en el cl\u00faster Patroni y DCS se actualiza a intervalos espec\u00edficos. Creo que el valor predeterminado de ttl es de 30 segundos.<\/p>\n<p><\/p>\n<p>Por lo tanto, puede haber una situaci\u00f3n en la que el retraso de replicaci\u00f3n para las r\u00e9plicas en el DCS sea uno, mientras que en realidad puede haber un retraso completamente diferente o, de hecho, puede que no haya retraso alguno, es decir, esta cosa no es en tiempo real. Y no siempre refleja la imagen real. No vale la pena construir una l\u00f3gica compleja sobre ello. <\/p>\n<p><\/p>\n<p>Y el riesgo de p\u00e9rdidas siempre permanece. Y en el peor de los casos, una f\u00f3rmula, y en el caso promedio, otra f\u00f3rmula. Es decir, cuando planeamos la implementaci\u00f3n de Patroni y evaluamos cu\u00e1ntos datos podemos perder, debemos basarnos en estas f\u00f3rmulas y tener una idea aproximada de cu\u00e1ntos datos podemos perder. <\/p>\n<p><\/p>\n<p>Y hay una buena noticia. Cuando el viejo maestro se ha adelantado, puede haberse adelantado debido a algunos procesos de fondo. Es decir, hubo un autovacuum, escribi\u00f3 datos, los guard\u00f3 en el registro de transacciones. Y esos datos podemos ignorar f\u00e1cilmente y perder. No hay ning\u00fan problema en ello. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a86e8971ab4ef41b89af9cf0bdf519ba.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y as\u00ed se ven los registros en caso de que se establezca maximum_lag_on_failover y ocurra un failover, y sea necesario elegir un nuevo maestro. La r\u00e9plica se eval\u00faa a s\u00ed misma como incapaz de participar en las elecciones. Y se niega a participar en la carrera por ser el l\u00edder. Y espera a que se elija un nuevo maestro para luego conectarse a \u00e9l. Esta es una medida adicional contra la p\u00e9rdida de datos.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. 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=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/c32f26e7526e1873f3bfd7d3693fcc72.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqu\u00ed nuestro equipo de producto escribi\u00f3 que su producto tiene problemas al trabajar con Postgres. Al mismo tiempo, no se puede acceder al propio maestro porque no est\u00e1 disponible por SSH. Y el auto-failover tampoco ocurre. <\/p>\n<p><\/p>\n<p>Este host fue forzado a reiniciarse. Debido al reinicio, ocurri\u00f3 un auto-failover, aunque podr\u00eda haberse realizado un failover manual, como entiendo ahora. Y despu\u00e9s del reinicio, ya vamos a ver qu\u00e9 pas\u00f3 con el maestro actual. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/95efb82e0647a396a21683cd53a69547.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y al mismo tiempo, ya sab\u00edamos de antemano que ten\u00edamos problemas con los discos, es decir, ya ten\u00edamos conocimiento por monitoreo de d\u00f3nde investigar y qu\u00e9 buscar. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/367aaab607d833d96a573ddbbbced502.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Revisamos el registro de postgres, comenzamos a ver qu\u00e9 estaba sucediendo. Vimos commits que duraban de uno a tres segundos, lo cual no es normal. Vimos que nuestro autovacuum se iniciaba muy lentamente y de manera extra\u00f1a. Y vimos archivos temporales en el disco. Es decir, todos estos son indicadores de problemas con los discos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/7e0cfce7a81901ef9ef736c3fefc8dce.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Examinamos el dmesg del sistema (en el registro de mensajes del n\u00facleo). Y vimos que ten\u00edamos problemas con uno de los discos. La subsistema de discos representaba un software Raid. Revisamos \/proc\/mdstat y vimos que faltaba un disco. Es decir, aqu\u00ed hay un Raid de 8 discos, nos falta uno. Si miramos detenidamente la diapositiva, podemos ver que nos falta sde. Es como si, por decirlo de alguna manera, se hubiera ca\u00eddo un disco. Esto activ\u00f3 problemas en los discos, y las aplicaciones tambi\u00e9n experimentaron problemas al trabajar con el cl\u00faster de Postgres.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/4b09b3aa761cb504fa79173ef280faac.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y en este caso, Patroni no nos habr\u00eda ayudado, porque Patroni no tiene la tarea de monitorear el estado del servidor ni el estado del disco. Debemos rastrear este tipo de situaciones con monitoreo externo. Agregamos r\u00e1pidamente el monitoreo de discos al monitoreo externo. <\/p>\n<p><\/p>\n<p>Y se nos ocurri\u00f3 la idea: \u00bfpodr\u00eda ayudarnos el fencing o un watchdog de software? Pensamos que probablemente no nos ayudar\u00eda en este caso, porque durante los problemas, Patroni continu\u00f3 interactuando con el cl\u00faster DCS y no vio ning\u00fan problema. Es decir, desde el punto de vista del DCS y de Patroni, todo estaba bien en el cl\u00faster, aunque de hecho hubo problemas con el disco y problemas de disponibilidad de la base de datos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/15fdac78535355d4eb889efcc27efc46.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En mi opini\u00f3n, este es uno de los problemas m\u00e1s extra\u00f1os, que investigu\u00e9 durante mucho tiempo, le\u00ed muchos registros y lo llam\u00e9 simulador de cl\u00faster. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/b5259774931c290eda6673deb14b6c48.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El problema era que el antiguo maestro no pod\u00eda convertirse en una r\u00e9plica normal, es decir, Patroni lo iniciaba, Patroni mostraba que este nodo estaba presente como r\u00e9plica, pero al mismo tiempo no era una r\u00e9plica normal. Ahora ver\u00e1n por qu\u00e9. Esto lo tengo guardado desde el an\u00e1lisis de aquel problema. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/c35a5d102a46764bbf96e5a75ee88171.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfY c\u00f3mo comenz\u00f3 todo? Comenz\u00f3, al igual que en el problema anterior, con lentitud en los discos. Ten\u00edamos confirmaciones de uno o dos por segundo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/435c1b350a89f288e0e10ca9d5a2ec6e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hubo interrupciones de conexiones, es decir, los clientes se desconectaban. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/920cb1f3f3b40578e15e6ff711e85c50.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hubo bloqueos de diversas severidades. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/285d6292d89b928a85e95602ee57d38a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y, por lo tanto, la subsistema de discos no era muy receptiva. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ebe71d49360e7f604ecd6a3c8276cb73.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y lo m\u00e1s misterioso para m\u00ed fue la solicitud de apagado inmediato que lleg\u00f3. Postgres tiene tres modos de apagado:<\/p>\n<p><\/p>\n<ul>\n<li>El modo graceful, donde esperamos a que todos los clientes se desconecten de forma aut\u00f3noma. <\/li>\n<li>El modo fast, donde obligamos a los clientes a desconectarse porque vamos a apagar. <\/li>\n<li>Y inmediato. En este caso, inmediato ni siquiera informa a los clientes que deben desconectarse, simplemente se apaga sin previo aviso. Y a todos los clientes, el sistema operativo env\u00eda un mensaje RST (mensaje TCP que indica que la conexi\u00f3n se ha interrumpido y que el cliente no tiene nada m\u00e1s que buscar). <\/li>\n<\/ul>\n<p><\/p>\n<p>\u00bfQui\u00e9n envi\u00f3 esta se\u00f1al? Los procesos en segundo plano de Postgres no se env\u00edan tales se\u00f1ales entre s\u00ed, es decir, es un kill-9. No se env\u00edan entre ellos, solo reaccionan a ello, es decir, es un reinicio de emergencia de Postgres. No s\u00e9 qui\u00e9n lo envi\u00f3. <\/p>\n<p><\/p>\n<p>Mirei el comando 'last' y vi a una persona que tambi\u00e9n inici\u00f3 sesi\u00f3n en este servidor junto con nosotros, pero me dio verg\u00fcenza preguntar. Quiz\u00e1s fue un kill -9. Ver\u00eda en los logs un kill -9, porque Postgres registra que recibi\u00f3 un kill -9, pero no lo vi en los logs. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fe8e844649cea3384ebfde86e36eba44.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Investigando m\u00e1s, vi que Patroni no hab\u00eda escrito en el log durante bastante tiempo: 54 segundos. Y si comparamos dos timestamps, aqu\u00ed aproximadamente 54 segundos no hubo mensajes. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ffb1c4db3d7de591d77d56ed2fcc4f2a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y durante ese tiempo ocurri\u00f3 un failover autom\u00e1tico. Patroni funcion\u00f3 perfectamente aqu\u00ed. Nuestro antiguo maestro estaba inalcanzable, algo le estaba sucediendo. Y comenzaron las elecciones de un nuevo maestro. Todo funcion\u00f3 bien aqu\u00ed. pgsql01 se convirti\u00f3 en el nuevo l\u00edder. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/6b2457653e9f77af44cd64b4aff021a0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tenemos una r\u00e9plica que se convirti\u00f3 en maestro. Y hay una segunda r\u00e9plica. Y hubo problemas con la segunda r\u00e9plica. Estaba intentando reconfigurarse. Seg\u00fan entiendo, intentaba cambiar recovery.conf, reiniciar Postgres y conectarse al nuevo maestro. Cada 10 segundos escribe mensajes indicando que lo intenta, pero no lo logra. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/381818f189e19c3e1154074b4652f837.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y durante esos intentos, un se\u00f1al de immediate-shutdown llega al antiguo maestro. El maestro se reinicia. Y tambi\u00e9n se detiene la recuperaci\u00f3n, porque el antiguo maestro se reinicia. Es decir, la r\u00e9plica no puede conectarse a \u00e9l porque est\u00e1 en modo apagado. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/d8a8cde925fa8fe601d44ab908ae69dc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En alg\u00fan momento funcion\u00f3, pero la replicaci\u00f3n no se inici\u00f3. <\/p>\n<p><\/p>\n<p>Tengo una \u00fanica hip\u00f3tesis: que en recovery.conf hab\u00eda la direcci\u00f3n del antiguo maestro. Y cuando apareci\u00f3 el nuevo maestro, la segunda r\u00e9plica todav\u00eda intentaba conectarse al antiguo maestro. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/425ea3af1f1e186f4760e1fb1f5419fa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cuando Patroni se inici\u00f3 en la segunda r\u00e9plica, el nodo se inici\u00f3, pero no pudo conectarse a la replicaci\u00f3n. Y surgi\u00f3 un retraso en la replicaci\u00f3n que se ve\u00eda m\u00e1s o menos as\u00ed. Es decir, los tres nodos estaban en su lugar, pero el segundo nodo estaba atrasado. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/f564eacd9944666c9a3f5bea634ede6b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sin embargo, si miras los registros que se escribieron, se pod\u00eda ver que la replicaci\u00f3n no pod\u00eda iniciarse porque los registros de transacciones eran diferentes. Y los registros de transacciones que ofrece el maestro, que est\u00e1n indicados en recovery.conf, simplemente no son adecuados para nuestro nodo actual. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/6b09947d157c9ef0a190da2df2cb5892.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y aqu\u00ed comet\u00ed un error. Deb\u00ed haber ido a verificar qu\u00e9 hab\u00eda en recovery.conf para comprobar mi hip\u00f3tesis de que nos est\u00e1bamos conectando al maestro equivocado. Pero en ese momento apenas estaba aprendiendo sobre esto y no se me ocurri\u00f3, o vi que la replicaci\u00f3n estaba desactualizada y tendr\u00eda que volver a configurarla; es decir, de alguna manera lo manej\u00e9 de forma descuidada. Fue mi fallo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/159f2256fd81428fd0d82a255528887d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Treinta minutos despu\u00e9s, lleg\u00f3 el administrador; es decir, reinici\u00e9 Patroni en la r\u00e9plica. Ya hab\u00eda perdido la esperanza en ella, pensaba que tendr\u00eda que volver a configurarla. Y pens\u00e9: voy a reiniciar Patroni, tal vez algo bueno suceda. Se inici\u00f3 la recuperaci\u00f3n. Y la base de datos incluso se abri\u00f3, estaba lista para aceptar conexiones. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/aeac98750386c8389d39e006a229cc85.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La replicaci\u00f3n se inici\u00f3. Pero despu\u00e9s de un minuto, se cay\u00f3 con un error de que los registros de transacciones no eran adecuados. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/17eaba000a79c80c29d1bc3902de05e6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pens\u00e9 que lo volver\u00eda a reiniciar. Reinici\u00e9 Patroni otra vez, y no reinici\u00e9 Postgres, sino que reinici\u00e9 espec\u00edficamente Patroni, con la esperanza de que iniciara la base de datos de manera m\u00e1gica. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a85b38e033c45ad73da317f41e0ef24a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La replicaci\u00f3n se reinici\u00f3, pero las marcas en el registro de transacciones eran diferentes, no eran las que estaban en el intento anterior. La replicaci\u00f3n se detuvo nuevamente. Y el mensaje era un poco diferente. Y no era muy informativo para m\u00ed. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/fd90d708230bd54af685786c7e361ee1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y aqu\u00ed se me ocurri\u00f3: \u00bfqu\u00e9 tal si reinicio Postgres y, en ese momento, en el maestro actual hago un checkpoint para mover el punto en el registro de transacciones un poco m\u00e1s adelante, para que la recuperaci\u00f3n comience desde otro momento? Adem\u00e1s, ten\u00edamos espacio de WAL disponible. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/19e67f95d1a74141a013947c9aa39e38.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Reinici\u00e9 Patroni, hice un par de checkpoints en el maestro, unos puntos de reinicio en la r\u00e9plica cuando se abri\u00f3. Y eso ayud\u00f3. Pens\u00e9 mucho sobre por qu\u00e9 eso ayud\u00f3 y c\u00f3mo funcion\u00f3. Y la r\u00e9plica se inici\u00f3. Y la replicaci\u00f3n no se interrumpi\u00f3 m\u00e1s. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/418ca59a681be84f51ed374a73a759c9.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Este problema es uno de los m\u00e1s enigm\u00e1ticos para m\u00ed, sobre el que a\u00fan sigo reflexionando, sobre qu\u00e9 estaba ocurriendo realmente. <\/p>\n<p><\/p>\n<p>\u00bfCu\u00e1les son las conclusiones aqu\u00ed? Patroni puede funcionar como se espera y sin errores. Pero esto no garantiza al 100 % que todo est\u00e9 bien. La r\u00e9plica puede iniciarse, pero puede estar en un estado semi-operativo, y la aplicaci\u00f3n no puede trabajar con esa r\u00e9plica porque contendr\u00e1 datos antiguos. <\/p>\n<p><\/p>\n<p>Y despu\u00e9s de cada failover, siempre debemos verificar que todo est\u00e9 en orden con el cl\u00faster, es decir, que haya el n\u00famero adecuado de r\u00e9plicas y que no haya latencia en la replicaci\u00f3n.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/aca7047ff33d3efe14071b798b554091.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y a medida que reviso estos problemas, formular\u00e9 recomendaciones. Intent\u00e9 agruparlas en dos diapositivas. Probablemente, todas las historias se podr\u00edan haber resumido en dos diapositivas y solo contar eso.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/d4ad31b26d83c8846fe4097a11d70849.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cuando usas Patroni, es imprescindible tener monitoreo. Siempre debes saber cu\u00e1ndo ocurri\u00f3 un failover autom\u00e1tico, porque si no sabes que hubo un failover autom\u00e1tico, no est\u00e1s controlando el cl\u00faster. Y eso es malo.<\/p>\n<p><\/p>\n<p>Despu\u00e9s de cada failover, siempre debemos verificar manualmente el cl\u00faster. Debemos asegurarnos de que siempre tengamos el n\u00famero adecuado de r\u00e9plicas, que no haya latencia en la replicaci\u00f3n, y que en los registros no haya errores relacionados con la replicaci\u00f3n en flujo, con Patroni, o con el sistema DCS.<\/p>\n<p><\/p>\n<p>La automatizaci\u00f3n puede funcionar con \u00e9xito; Patroni es una herramienta muy buena. Puede funcionar, pero eso no llevar\u00e1 al cl\u00faster al estado deseado. Y si no nos enteramos de ello, tendremos problemas.<\/p>\n<p><\/p>\n<p>Y Patroni no es una balas de plata. A\u00fan debemos tener una comprensi\u00f3n de c\u00f3mo funciona Postgres, c\u00f3mo se lleva a cabo la replicaci\u00f3n y c\u00f3mo Patroni opera con Postgres, as\u00ed como asegurar la interacci\u00f3n entre los nodos. Esto es necesario para poder solucionar los problemas que surgen manualmente.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/ea4162df3561d2ea7001f2ef6788eaaa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfC\u00f3mo abordo la cuesti\u00f3n del diagn\u00f3stico? Ha sucedido que trabajamos con diferentes clientes y nadie tiene un stack ELK, as\u00ed que necesito revisar los registros abriendo 6 consolas y 2 pesta\u00f1as. En una pesta\u00f1a est\u00e1n los registros de Patroni para cada nodo, en la otra pesta\u00f1a est\u00e1n los registros de Consul, o Postgres si es necesario. Diagnosticar esto es muy complicado. <\/p>\n<p><\/p>\n<p>\u00bfQu\u00e9 enfoques he desarrollado? Primero, siempre miro cu\u00e1ndo ocurri\u00f3 el failover. Y para m\u00ed, este es un punto de inflexi\u00f3n. Observo lo que sucedi\u00f3 antes del failover, durante el failover y despu\u00e9s del failover. Un failover tiene dos marcas: el tiempo de inicio y el tiempo de finalizaci\u00f3n. <\/p>\n<p><\/p>\n<p>Luego, reviso en los registros los eventos previos al failover, es decir, estoy buscando las causas por las que ocurri\u00f3 el failover. <\/p>\n<p><\/p>\n<p>Y esto proporciona una imagen de lo que sucedi\u00f3 y qu\u00e9 se puede hacer en el futuro para evitar que tales circunstancias ocurran (y, como resultado, un failover).<\/p>\n<p><\/p>\n<p>\u00bfY a d\u00f3nde miramos normalmente? Yo miro:<\/p>\n<p><\/p>\n<ul>\n<li>Primero en los registros de Patroni. <\/li>\n<li>Luego reviso los registros de Postgres, o los registros de DCS dependiendo de lo que se encuentre en los registros de Patroni. <\/li>\n<li>Y los registros del sistema tambi\u00e9n a veces dan una idea de qu\u00e9 fue lo que caus\u00f3 el failover. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/a53618e366020e1a550d852fc308c188.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfQu\u00e9 opin\u00f3 de Patroni? Tengo una muy buena opini\u00f3n de Patroni. En mi opini\u00f3n, es lo mejor que hay hoy en d\u00eda. Conozco muchos otros productos. Son Stolon, Repmgr, Pg_auto_failover, PAF. Cuatro herramientas. Las he probado todas. A Patroni le tengo m\u00e1s aprecio. <\/p>\n<p><\/p>\n<p>Si me preguntan: \"\u00bfRecomiendo Patroni?\". Dir\u00e9 que s\u00ed, porque me gusta Patroni. Y, me parece que he aprendido a configurarlo. <\/p>\n<p><\/p>\n<p>Si te interesa ver qu\u00e9 otros problemas hay con Patroni, aparte de los problemas que he mencionado, siempre puedes ir a la p\u00e1gina <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\/issues\/\">issues<\/a><\/noindex> en GitHub. Hay muchas historias diferentes y se discuten muchos problemas interesantes. Y, al final, se han reportado y resuelto algunos errores, es decir, es una lectura interesante. <\/p>\n<p><\/p>\n<p>Ah\u00ed hay historias interesantes sobre c\u00f3mo la gente se dispara en el pie. Muy instructivo. Lees y entiendes que as\u00ed no se debe hacer. Ya he tomado nota. <\/p>\n<p><\/p>\n<p>Y quisiera dar un gran agradecimiento a la empresa Zalando por desarrollar este proyecto, en particular a Alexander Kukushkin y Alexey Klyukin. Alexey Klyukin es uno de los co-autores, ya no trabaja en Zalando, pero son dos personas que empezaron a trabajar con este producto. <\/p>\n<p><\/p>\n<p>Y creo que Patroni es una herramienta muy genial. Estoy contento de que exista, es interesante de usar. Y muchas gracias a todos los contribuidores que escriben parches para Patroni. Espero que Patroni se vuelva m\u00e1s maduro, genial y funcional con el tiempo. Ya es funcional, pero espero que siga mejorando. As\u00ed que si planeas usar Patroni, no temas. Es una buena soluci\u00f3n, se puede implementar y usar. <\/p>\n<p><\/p>\n<p>Eso es todo. Si tienes preguntas, no dudes en preguntar.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Historias de Fallos de Patroni o C\u00f3mo hacer que su cl\u00faster de PostgreSQL se caiga. Alexey Lesovskiy\" src=\"\/wp-content\/uploads\/2020\/07\/85c2fef2455999b48413c9fc3b235ed6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Preguntas<\/p>\n<p><\/p>\n<p><em>\u00a1Gracias por la presentaci\u00f3n! Si despu\u00e9s del failover todav\u00eda hay que revisarlo con mucho cuidado, \u00bfentonces para qu\u00e9 necesitamos un failover autom\u00e1tico?<\/em> <\/p>\n<p><\/p>\n<p>Porque es algo nuevo. Solo hemos estado trabajando con ello durante un a\u00f1o. Es mejor ser precavido. Queremos entrar y ver que todo realmente ha funcionado como se supone. Ese es un nivel de desconfianza adulta: es mejor verificar y comprobar. <\/p>\n<p><\/p>\n<p><em>Por ejemplo, entramos y miramos por la ma\u00f1ana, \u00bfverdad?<\/em><\/p>\n<p><\/p>\n<p>No por la ma\u00f1ana, normalmente nos enteramos del failover pr\u00e1cticamente de inmediato. Recibimos notificaciones y vemos que ha ocurrido un failover. Casi de inmediato entramos y revisamos. Pero todas esas comprobaciones deben entrar en el nivel de monitoreo. Si consultamos a Patroni a trav\u00e9s de la API REST, hay un historial. A trav\u00e9s del historial se pueden ver las marcas de tiempo cuando ocurri\u00f3 el failover. Con base en eso se puede hacer un monitoreo. Se puede ver el historial, cu\u00e1ntos eventos han ocurrido. Si tenemos m\u00e1s eventos, significa que ocurri\u00f3 un failover autom\u00e1tico. Podemos verificar y ver. O nuestra automatizaci\u00f3n en el monitoreo comprob\u00f3 que todas nuestras r\u00e9plicas est\u00e1n en su lugar, no hay retraso y todo est\u00e1 bien. <\/p>\n<p><\/p>\n<p><em>\u00a1Gracias!<\/em><\/p>\n<p><\/p>\n<p><em>\u00a1Muchas gracias por la excelente charla! Si llevamos el cl\u00faster DCS a alg\u00fan lugar alejado del cl\u00faster de Postgres, \u00bftambi\u00e9n hay que mantener este cl\u00faster peri\u00f3dicamente? \u00bfCu\u00e1les son las mejores pr\u00e1cticas para apagar algunas partes del cl\u00faster DCS, hacer algo con ellas, etc.? \u00bfC\u00f3mo vive toda esta estructura durante esto? \u00bfY c\u00f3mo se deben hacer estas cosas?<\/em><\/p>\n<p><\/p>\n<p>Para una empresa, fue necesario hacer una matriz de problemas, que detalla qu\u00e9 sucede si alguno o varios componentes fallan. Con esta matriz, revisamos todos los componentes en secuencia y construimos escenarios en caso de que esos componentes fallen. Por lo tanto, para cada escenario de falla, se puede tener un plan de acci\u00f3n para la recuperaci\u00f3n. Y en el caso de DCS, esto se considera parte de la infraestructura est\u00e1ndar. As\u00ed que el administrador se encarga de ello y ya confiamos en los administradores que lo manejan y en su capacidad para repararlo en caso de fallos. Si no hay DCS, lo desplegamos nosotros, pero no lo monitoreamos espec\u00edficamente porque no somos responsables de la infraestructura, aunque damos recomendaciones sobre qu\u00e9 y c\u00f3mo monitorear. <\/p>\n<p><\/p>\n<p><em>Es decir, \u00bfhe entendido correctamente que hay que desactivar Patroni, desactivar el failover, desactivar todo antes de hacer algo con los hosts?<\/em><\/p>\n<p><\/p>\n<p>Esto depende de cu\u00e1ntos nodos tengamos en el cl\u00faster DCS. Si hay muchos nodos y si solo estamos fallando uno de los nodos (r\u00e9plica), el cl\u00faster mantiene su qu\u00f3rum. Y Patroni sigue operativo. No se dispara nada. Si tenemos operaciones complejas que afectan a m\u00e1s nodos, cuya ausencia puede romper el qu\u00f3rum, entonces, s\u00ed, tal vez tenga sentido pausar Patroni. Hay un comando correspondiente: patronictl pause, patronictl resume. Simplemente hacemos una pausa, y el autofailover no se activa en ese momento. Realizamos mantenimiento en el cl\u00faster DCS, luego levantamos la pausa y continuamos operando.<\/p>\n<p><\/p>\n<p><em>\u00a1Muchas gracias!<\/em><\/p>\n<p><\/p>\n<p><em>\u00a1Muchas gracias por la presentaci\u00f3n! \u00bfQu\u00e9 opina el equipo de producto sobre la posible p\u00e9rdida de datos?<\/em> <\/p>\n<p><\/p>\n<p>Al equipo de producto no le importa, pero los l\u00edderes de equipo est\u00e1n preocupados. <\/p>\n<p><\/p>\n<p><em>\u00bfQu\u00e9 garant\u00edas existen?<\/em><\/p>\n<p><\/p>\n<p>Es muy dif\u00edcil dar garant\u00edas. Hay una presentaci\u00f3n de Alexander Kukushkin sobre 'C\u00f3mo calcular RPO y RTO', es decir, el tiempo de recuperaci\u00f3n y cu\u00e1ntos datos podemos perder. Creo que necesitamos encontrar esas diapositivas y estudiarlas. Por lo que recuerdo, hay pasos concretos sobre c\u00f3mo calcular estas cosas. Cu\u00e1ntas transacciones podemos perder, cu\u00e1ntos datos podemos perder. Como opci\u00f3n, podemos usar replicaci\u00f3n s\u00edncrona a nivel de Patroni, pero esto es una espada de doble filo: o tenemos fiabilidad de datos o perdemos en velocidad. Existe replicaci\u00f3n s\u00edncrona, pero tampoco garantiza una protecci\u00f3n del 100% contra la p\u00e9rdida de datos.<\/p>\n<p><\/p>\n<p><em>Alexey, gracias por la excelente presentaci\u00f3n. \u00bfTienes experiencia usando Patroni para protecci\u00f3n de nivel cero? Es decir, en conjunto con un standby s\u00edncrono. Esa es la primera pregunta. Y la segunda pregunta. Has utilizado diferentes soluciones. Nosotros usamos Repmgr, pero sin autofailover y ahora estamos planeando a\u00f1adir autofailover. Y estamos considerando a Patroni como una soluci\u00f3n alternativa. \u00bfQu\u00e9 puedes decir a favor de Patroni en comparaci\u00f3n con Repmgr?<\/em><\/p>\n<p><\/p>\n<p>La primera pregunta fue sobre r\u00e9plicas s\u00edncronas. Nadie usa replicaci\u00f3n s\u00edncrona porque todos tienen miedo (Ya hay varios clientes que la utilizan, en principio no han notado problemas de rendimiento \u2014 <em>Nota del presentador<\/em>). Pero nosotros hemos establecido una regla de que en un cl\u00faster de replicaci\u00f3n s\u00edncrona debe haber al menos tres nodos, porque si tenemos dos nodos y el maestro o una r\u00e9plica falla, Patroni convierte ese nodo en modo standalone para que la aplicaci\u00f3n contin\u00fae funcionando. En este caso, hay riesgos de p\u00e9rdida de datos.<\/p>\n<p><\/p>\n<p>Respecto a la segunda pregunta, hemos utilizado Repmgr y todav\u00eda lo usamos con algunos clientes por razones hist\u00f3ricas. \u00bfQu\u00e9 se puede decir? En Patroni, el auto failover viene por defecto, mientras que en Repmgr es una funci\u00f3n adicional que necesita ser habilitada. Es necesario ejecutar el daemon de Repmgr en cada nodo y entonces podemos configurar el auto failover. <\/p>\n<p><\/p>\n<p>Repmgr verifica si los nodos de Postgres est\u00e1n vivos. Los procesos de Repmgr verifican la existencia entre s\u00ed, lo cual no es un enfoque muy eficiente, ya que pueden ocurrir casos complejos de aislamiento de red en los que un gran cl\u00faster de Repmgr puede dividirse en varios m\u00e1s peque\u00f1os y continuar funcionando. No sigo Repmgr desde hace tiempo, tal vez esto lo hayan solucionado... o tal vez no. Sin embargo, extraer la informaci\u00f3n sobre el estado del cl\u00faster en DCS, como lo hacen Stolon y Patroni, es la opci\u00f3n m\u00e1s viable. <\/p>\n<p><\/p>\n<p><em>Alexey, tengo una pregunta, quiz\u00e1s algo b\u00e1sica. En uno de los primeros ejemplos sacaste DCS de una m\u00e1quina local a un nodo remoto. Entendemos que la red es algo que tiene sus particularidades, vive por s\u00ed misma. \u00bfY qu\u00e9 pasar\u00e1 si por alguna raz\u00f3n el cl\u00faster DCS se vuelve inaccesible? No mencionar\u00e9 las razones, pueden ser muchas: desde manos torpes de los administradores de red hasta problemas reales.<\/em> <\/p>\n<p><\/p>\n<p>No lo mencion\u00e9 en voz alta, pero el cl\u00faster DCS tambi\u00e9n debe ser tolerante a fallos, es decir, debe tener un n\u00famero impar de nodos para que se pueda alcanzar un qu\u00f3rum. \u00bfQu\u00e9 ocurre si el cl\u00faster DCS se vuelve inaccesible o no se puede reunir el qu\u00f3rum, es decir, si hay un cortocircuito de red o falla en los nodos? En este caso, el cl\u00faster Patroni pasa a modo de solo lectura. El cl\u00faster Patroni no puede determinar el estado del cl\u00faster ni qu\u00e9 hacer. No puede comunicarse con DCS y guardar el nuevo estado del cl\u00faster, por lo que todo el cl\u00faster pasa a modo de solo lectura. Y espera o intervenci\u00f3n manual del operador o la recuperaci\u00f3n de DCS.<\/p>\n<p><\/p>\n<p><em>En t\u00e9rminos simples, \u00bfse convierte DCS en un servicio tan importante para nosotros como la propia base de datos?<\/em><\/p>\n<p><\/p>\n<p>S\u00ed, s\u00ed. En muchas empresas modernas, el Service Discovery es una parte integral de la infraestructura. Se implementa incluso antes de que exista una base de datos en la infraestructura. En otras palabras, lanzamos la infraestructura, nos desplegamos en el centro de datos y ya tenemos el Service Discovery. Si es Consul, se puede construir sobre \u00e9l y el DNS. Si es Etcd, podr\u00eda ser parte de un cl\u00faster de Kubernetes, donde ya se desplegar\u00e1 todo lo dem\u00e1s. Me parece que el Service Discovery ya es una parte indispensable de las infraestructuras modernas. Y se considera mucho antes que las bases de datos. <\/p>\n<p><\/p>\n<p><em>\u00a1Gracias!<\/em><\/p>\n<p>Fuente: <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.2 - 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\/es\/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.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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\udd47Historias de fallos de Patroni o c\u00f3mo hacer colapsar tu cl\u00faster de PostgreSQL. Alexey Lesovski | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/es\/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":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/90103","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=90103"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/90103\/revisions"}],"predecessor-version":[{"id":158759,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/90103\/revisions\/158759"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/90104"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=90103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=90103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=90103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}