sql >> Base de Datos >  >> RDS >> PostgreSQL

Una guía para PGpool - Sugerencias y observaciones:Tercera parte

En la parte anterior me atreví a jugar con una característica no implementada fantaseando como funcionaría. Bueno, HA en primer lugar es una cuestión de diseño y solo luego de implementación. No excusa la mala implementación, ni hace que el diseño ingenuo parezca inteligente. Sin embargo, después de cubrir todos los escenarios posibles y encontrar la mejor regla adecuada para la mayoría de los casos, a veces un pequeño cambio muy primitivo puede arruinar la fortaleza. A continuación quiero sandbox.

¿Qué sucede cuando pgpool debería conmutar por error, pero no puede?

Cuando la verificación de estado falla para el maestro, el comando failover_command se activa para degenerar todo o promover el siguiente esclavo a principal. Suena sólido. ¿Qué sucede si falla, por ejemplo, la conexión ssh falla (por ejemplo, porque otro administrador incorrecto eliminó la clave de ~/.ssh/authorized_keys)? ¿Qué tenemos?

Tan pronto como health_check_timeout (predeterminado 20) está fuera (también afectado por el retraso de reintento, el máximo se retira, etc.), el nodo se vuelve inactivo, por lo que:

t=# select nid,port,st from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
 nid | port |  st
-----+------+------
   0 | 5400 | down
   1 | 5401 | up
   2 | 5402 | up
(3 rows)

Por lo tanto, no quedan reintentos y la conmutación por error falló. La primera opción, obviamente, es realizar la conmutación por error manualmente. Pero si la conmutación por error falla debido a un error estúpido, el maestro está de vuelta en los rieles, y el único problema que tiene es que pgpool piensa que el maestro está fuera de línea; probablemente querrá dejar las cosas como solían estar antes del accidente, ¿verdad? Por supuesto, no basta con volver a poner el maestro en línea. Pgpool ya “degeneró” el primario. Simplemente agregarlo como un nuevo nodo tampoco ayudará. Lo peor es que, después del evento, pgpool no intentará verificar si el antiguo maestro es pg_is_in_recovery() o no, por lo que nunca lo aceptará como Primario. De acuerdo con la pista de errores, debe "Descartar el archivo pgpool_status y no restaurar el estado anterior" con el comando pgpool -D.

Después de descartar el estado, nos volvemos a conectar para evitar que el servidor cierre la conexión de forma inesperada y ejecute:

t=# select nid,port,st,role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
 nid | port | st |  role
-----+------+----+---------
   0 | 5400 | up | primary
   1 | 5401 | up | standby
   2 | 5402 | up | standby
(3 rows)

Todos los nodos están nuevamente en funcionamiento, pgpool reconoce al maestro.

Finalmente, quiero cubrir algunos consejos y observaciones sobre el uso de pgpool:

  • Cambiar la configuración de back-end es un poco complicado:el nombre de host, el puerto y el directorio requieren recarga para agregar nuevos nodos, pero requieren reiniciar para editar los existentes. Mientras que el peso y la bandera se pueden modificar con solo recargar.

  • No confunda los valores de la columna load_balance_node con la configuración. Si ve solo un nodo con verdadero, no solo está bien, es así. No significa que solo tiene un nodo en el grupo de equilibrio, solo muestra qué nodo se elige para esta sesión en particular. A continuación se muestra el resultado de la consulta con los tres nodos que participan en el equilibrio de las sentencias SELECT, con el ID de nodo 2 elegido:

    t=# show pool_nodes;
     node_id | hostname  | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay
    ---------+-----------+------+--------+-----------+---------+------------+-------------------+-------------------
     0       | localhost | 5400 | up     | 0.125000  | primary | 61         | false             | 0
     1       | localhost | 5401 | up     | 0.312500  | standby | 8          | false             | 0
     2       | localhost | 5402 | up     | 0.562500  | standby | 11         | true              | 0
    (3 rows)
  • Puede verificar qué nodo se eligió para el equilibrio de carga con show pool_nodes, pero le importa saberlo para su consulta, no para "mostrar", por lo que dicha verificación no siempre es lo suficientemente informativa. Bueno, puede monitorear qué nodo usa para la consulta actual, con algo como:

    t=# select *,current_setting('port') from now();
                  now              | current_setting
    -------------------------------+-----------------
     2018-04-09 13:56:17.501779+01 | 5401
    (1 row)

¡Importante! Pero no:

t=# select now, setting from now() join pg_settings on name='port';
             now             | setting
-----------------------------+---------
 2018-04-09 13:57:17.5229+01 | 5400
(1 row)

Como SIEMPRE devolverá el puerto del maestro. Lo mismo aplica para cualquier pg_catalog SELECT.

  • Como notó en partes anteriores, uso una forma más complicada que simplemente mostrar pool_nodes para enumerar los nodos con el estado. Lo hago deliberadamente para demostrar cómo puede hacer que el resultado sea manejable. Usar where hace que la consulta sea más larga, pero el resultado claro, omitiendo todo lo que distrae la atención para nuestra tarea en particular. Comparar:

t=# select nid,port,st,role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
 nid | port | st |  role
-----+------+----+---------
   0 | 5400 | up | primary
   1 | 5401 | up | standby
   2 | 5402 | up | standby

Con la salida de show inicial pool_nodes...

  • No puedes comparar pgbouncer y pgpool. Pero si lo hace, lo más importante es saber que el análisis de consultas en pgpool depende de la versión de pg. Entonces, al actualizar PostgreSQL, también debe actualizar pgpool, mientras que una instancia de pgbouncer puede tener configuraciones para 8, 9, 10 clústeres diferentes en el mismo archivo ini.

  • ¿Por qué no puedo usar solo un script de conmutación por error en lugar de pgpool? Puede. Pero pgpool lo ofrece JUNTO con memcached y agrupación y equilibrio de conexiones y control de cerebro dividido y está comprobado por décadas de uso.

  • El sistema de seguimiento de errores está implementado; vale la pena visitarlo si trabaja con pgpool:https://www.pgpool.net/mantisbt/my_view_page.php

  • Numerosos errores tipográficos en la documentación, como bakance (backend + balance? ..), statemnet, allowd o discrepancia entre versiones (pool_nodes solía ser int y ahora son enumerados, pero el enlace a valores antiguos en pcp_node-info todavía está allí) estropea la impresión en este maravilloso producto. Sin embargo, un formulario para enviar el informe sobre el "error" encontrado en la documentación (al igual que "enviar corrección" en los documentos de Postgres) lo mejoraría enormemente.

  • Consejo importante: antes de confiar en cualquier paso, verifíquelo. P.ej. después de promocionar el nodo, no puede volver a promocionarlo (aquí la promoción no es una operación de postgres, sino el registro del nodo como maestro para pgpool):

    [email protected]:~# sudo -u postgres pcp_promote_node -w -h 127.0.0.1 -U vao -n 1
    pcp_promote_node -- Command Successful
    [email protected]:~# sudo -u postgres pcp_promote_node -w -h 127.0.0.1 -U vao -n 1
    FATAL:  invalid pgpool mode for process recovery request
    DETAIL:  specified node is already primary node, can't promote node id 1

Suena lógico y se ve genial. Sin embargo, si ejecuta esto en un nodo incorrecto (p. ej., el nodo 0 es ! pg_is_in_recovery):

[email protected]:~# for i in $(seq 1 3); do pcp_promote_node -w -h 127.0.0.1 -U vao -n 0; echo $?; done
pcp_promote_node -- Command Successful
0
pcp_promote_node -- Command Successful
0
pcp_promote_node -- Command Successful
0

Lo cual es malo porque no puede volver a promocionar el nodo y esperar un error, pero obtiene el estado de salida 0...

Descargue el documento técnico hoy Gestión y automatización de PostgreSQL con ClusterControl Obtenga información sobre lo que necesita saber para implementar, monitorear, administrar y escalar PostgreSQLDescargar el documento técnico

Consejo importante:no juegues demasiado. ¡Nunca juegues con prod!

Jugando con recovery_1st_stage_command usando pg_rewind, pensé probar, por curiosidad, otro truco de mono:consultar pgpool_recovery() sin argumentos (ya que los ignoro en mi configuración de todos modos) y luego tratar de adjuntar el nodo a pgpool:

[email protected]:~# psql -p 5433 -h localhost template1 -c "SELECT pgpool_recovery('or_1st.sh', '', '', '')"
 pgpool_recovery
-----------------
 t
(1 row)

[email protected]:~# pcp_attach_node -h 127.0.0.1 -U vao -w -n 1
pcp_attach_node -- Command Successful

Esta estúpida idea me llevó a:

[email protected]:~# ps -aef | grep pgpool
postgres 15227     1  0 11:22 ?        00:00:00 pgpool -D
postgres 15240 15227  0 11:22 ?        00:00:00 pgpool: health check process(0)
postgres 15241 15227  0 11:22 ?        00:00:00 pgpool: health check process(1)
postgres 15242 15227  0 11:22 ?        00:00:00 pgpool: health check process(2)
postgres 15648 15227  0 11:24 ?        00:00:00 [pgpool] <defunct>
postgres 16264 15227  0 11:26 ?        00:00:00 pgpool: PCP: wait for connection request
postgres 16266 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>
postgres 16506 16264  0 11:26 ?        00:00:00 pgpool: PCP: processing recovery request
postgres 16560 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>
postgres 16835 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>
postgres 16836 15227  0 11:26 ?        00:00:00 [pgpool] <defunct>

Sin escapatoria tengo que:

[email protected]:~# kill -9 
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.5433
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.9898

Por encima de 5433 está el puerto pgpool y 9898 es el puerto pcp. Obviamente, después del bloqueo, los archivos no se barren, por lo que debe hacerlo manualmente.

  • Haga una lectura cuidadosa y juegue mucho antes de llevar pgpool a producción. Es mucho más difícil encontrar ayuda con pgpool que con postgres. Algunas preguntas nunca son respondidas. Especialmente cuando se me preguntó en el lugar equivocado (la respondí basándome en el lugar correcto para obtener la respuesta)...
  • No olvide la línea de tiempo más reciente para la replicación en cascada (no es realmente la sugerencia de pgpool, pero a menudo las personas no entienden que para elegir un nuevo maestro no es suficiente especificar un punto final correcto para el receptor).
  • La arquitectura con el diagrama se puede encontrar aquí.

Conclusión

En 10 años aparecieron nuevas funciones prometedoras (perro guardián e IP virtual) y correcciones importantes (por ejemplo, serialize_accept), pero en general deja una impresión infravalorada. Los documentos tienen errores tipográficos que han vivido allí durante 10 años. No creo que nadie lea los documentos. No creo que nadie se haya dado cuenta. Simplemente no puedes denunciarlos de ninguna manera fácil. Hay un montón de armas cargadas y preparadas, tiradas en el sitio de documentación para que el usuario novato las tome, apunte contra el pie y apriete el gatillo. No tengo una idea razonable de cómo mejorarlo, solo advierto a los tiradores. Malinterpretar un parámetro puede ponerlo en una posición desesperada de ingeniería inversa para encontrar su error. Todos estos años, pgpool solía ser y sigue siendo una especie de producto para usuarios avanzados. Al leer la documentación, no pude evitar recordar el viejo chiste ruso sobre Sherlock Holmes:Sherlock y Watson vuelan en el globo. De repente, el fuerte viento los lleva a miles de kilómetros de distancia. Cuando pueden aterrizar, ven a la niña pastando ovejas. Holmes le pregunta a la niña:"Cariño, ¿dónde estamos?" y la niña responde “¡Estás en el globo!”. Sherlock agradece y mientras despegan dice “El viento nos llevó muy lejos, estamos en Rusia”. "¿Pero, como lo sabes?" pregunta Watson. "Es obvio:solo en Rusia los codificadores pastan ovejas", responde Sherlock. “Pero, ¿cómo sabes que la chica es programadora?” - “Es obvio, nos dio una respuesta absolutamente precisa y totalmente inútil”.