PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Um Guia para PGpool - Dicas e Observações:Parte Três


Na parte anterior eu ousei brincar com um recurso não implementado fantasiando como ele funcionaria. Bem HA em primeiro lugar é uma questão de design e só então implementação. Isso não justifica a má implementação, nem faz com que o design ingênuo pareça inteligente. No entanto, depois de cobrir todos os cenários possíveis e encontrar a melhor regra adequada para a maioria dos casos, às vezes uma pequena mudança muito primitiva pode arruinar a fortaleza. Abaixo eu quero sandbox.

O que acontece quando o pgpool deve fazer failover, mas não pode?


Quando a verificação de integridade do mestre falha, o failover_command é acionado para degenerar tudo ou promover o próximo escravo para primário. Parece sólido. E se ele falhar, por exemplo, a conexão ssh falha (por exemplo, porque outro - mau administrador remove a chave de ~/.ssh/authorized_keys). O que nós temos?

Assim que health_check_timeout (padrão 20) está fora (também afetado pelo atraso de repetição, max se aposenta e assim por diante), o nó fica inativo, então:
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)

Portanto, não há novas tentativas e o failover falhou. A primeira opção obviamente é fazer o failover manualmente. Mas se o failover falhou por causa de algum erro estúpido, o mestre está de volta aos trilhos, e o único problema que você tem é o pgpool pensar que o mestre está offline - você provavelmente gostaria de deixar as coisas como costumavam ser antes do acidente - certo? Claro que apenas mover o mestre de volta online não é suficiente. O Pgpool já “degenerou” o primário. Apenas adicioná-lo como um novo nó também não ajudará. O pior é que, após o evento, o pgpool não tentará verificar se o mestre antigo é pg_is_in_recovery() ou não, portanto, nunca o aceitará como Primário. De acordo com a trilha de bug, você deve “Descartar o arquivo pgpool_status e não restaurar o status anterior” com o comando pgpool -D.

Após descartar o status, reconectamos para evitar que o servidor encerre a conexão inesperadamente e execute:
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 os nós estão funcionando novamente, o pgpool reconhece o mestre.

Finalmente, quero dar algumas dicas e observações sobre o uso do pgpool:

  • Alterar as configurações de back-end é um pouco complicado:o nome do host, a porta e o diretório exigem recarga para adicionar novos nós, mas exigem reinicialização para editar os existentes. Enquanto o peso e a bandeira podem ser alterados com apenas recarregar.

  • Não confunda valores de coluna load_balance_node com configuração. Se você vir apenas um nó com true, não está apenas OK - é assim. Isso não significa que você tenha apenas um nó no pool de balanceamento - apenas mostra qual nó é escolhido para essa sessão específica. Abaixo está o resultado da consulta com todos os três nós participando do balanceamento de instruções SELECT, com o ID do nó 2 escolhido:
    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)

  • Você pode verificar qual nó foi escolhido para balanceamento de carga com show pool_nodes, mas você se importa em conhecê-lo para sua consulta, não para “show”, portanto, essa verificação nem sempre é informativa o suficiente. Bem, você pode monitorar qual nó você usa para a consulta atual, com algo como:
    t=# select *,current_setting('port') from now();
                  now              | current_setting
    -------------------------------+-----------------
     2018-04-09 13:56:17.501779+01 | 5401
    (1 row)

Importante! Mas não:
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 sempre retornará a porta do mestre. O mesmo se aplica a qualquer pg_catalog SELECT.

  • Como você notou nas partes anteriores, eu uso uma maneira mais complicada, do que apenas mostrar pool_nodes para listar nós com estado. Eu faço isso deliberadamente para demonstrar como você pode tornar o resultado gerenciável. Usar where torna a consulta mais longa, mas o resultado é claro, pulando tudo o que distrai a atenção para nossa tarefa específica. 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

Com a saída do show inicial pool_nodes...

  • Você não pode comparar pgbouncer e pgpool. Mas se você fizer isso, o mais importante é saber que a análise de consultas no pgpool depende da versão do pg. Portanto, ao atualizar o postgreSQL, você também precisa atualizar o pgpool, enquanto uma instância do pgbouncer pode ter configuração para 8,9,10 clusters diferentes no mesmo arquivo ini.

  • Por que não posso usar apenas um script de failover em vez de pgpool? Você pode. Mas o pgpool oferece JUNTO com memcached e pooling e balanceamento de conexões e controle de cérebro dividido e é verificado por décadas de uso.

  • O sistema de rastreamento de bugs está em vigor - vale a pena visitá-lo se você trabalha com pgpool:https://www.pgpool.net/mantisbt/my_view_page.php

  • Numerosos erros de digitação na documentação, como bakance (backend + balance?..), statemnet, permitido ou incompatibilidade entre a versão (pool_nodes costumava ser int e agora é enum, mas o link para valores antigos em pcp_node-info ainda está lá) estraga a impressão neste produto maravilhoso. Um formulário para enviar o relatório sobre o “bug” encontrado na documentação (assim como “enviar correção” nos documentos do postgres) melhoraria bastante.

  • Dica importante: antes de confiar em qualquer etapa - verifique-a. Por exemplo. depois de promover o node você não pode repromovê-lo (aqui promover não é a operação postgres, mas sim o registro do node como master 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

Parece lógico e parece ótimo. No entanto, se você executar isso no nó errado (por exemplo, o nó 0 é ! 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

O que é ruim porque você não pode promover novamente o nó e esperar um erro, mas obtém o status de saída 0…
Baixe o whitepaper hoje PostgreSQL Management &Automation with ClusterControlSaiba o que você precisa saber para implantar, monitorar, gerenciar e dimensionar o PostgreSQLBaixe o whitepaper
Dica importante:não jogue muito. Nunca jogue no prod!

Jogando com recovery_1st_stage_command usando pg_rewind, pensei em tentar por curiosidade outro hack de macaco - consultando pgpool_recovery() sem argumentos (já que eu os ignoro na minha configuração de qualquer maneira) e depois apenas tentando anexar o nó ao 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

Essa ideia estúpida me levou 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>

Sem escapatória eu tenho que:
[email protected]:~# kill -9 
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.5433
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.9898

Acima de 5433 é a porta pgpool e 9898 é a porta pcp. Obviamente, após a falha, os arquivos não são varridos, então você deve fazer isso manualmente.
  • Faça uma leitura cuidadosa e jogue bastante antes de levar o pgpool para a produção. É muito mais difícil encontrar ajuda com o pgpool do que o próprio postgres. Algumas perguntas nunca são respondidas. Especialmente quando perguntado no lugar errado (eu respondi com base no lugar certo para obter a resposta)...
  • Não se esqueça da linha do tempo mais recente para replicação em cascata (não é realmente a dica do pgpool, mas muitas vezes as pessoas não entendem que, para pegar um novo mestre, não é suficiente especificar um ponto de extremidade certo para o receptor).
  • l>
  • Arquitetura com diagrama pode ser encontrada aqui.

Conclusão


Em 10 anos surgiram novos recursos promissores (watchdog e ip virtual) e correções importantes (por exemplo, serialize_accept), mas no geral deixa uma impressão subvalorizada. Docs têm erros de digitação que moram lá há 10 anos. Eu não acredito que ninguém lê os documentos. Não acredito que ninguém tenha notado. Você simplesmente não pode denunciá-los de maneira fácil. Há uma abundância de armas carregadas e preparadas, no site de documentação para o usuário iniciante pegar, apontar contra o pé e puxar o gatilho. Não tenho uma ideia razoável de como melhorá-lo - estou apenas alertando os atiradores. A interpretação errada de um parâmetro pode colocá-lo em uma posição desesperada de engenharia reversa para encontrar seu erro. Todos esses anos o pgpool costumava ser e continua sendo um tipo de produto para usuários avançados. Lendo a documentação, não pude deixar de lembrar a velha piada russa sobre Sherlock Holmes:Sherlock e Watson voam no balão. De repente, o vento forte os leva a milhares de quilômetros de distância. Quando eles podem pousar, eles vêem a menina pastando ovelhas. Holmes pergunta à garota:“Querida, onde estamos?” e a menina responde “Você está no balão!”. Sherlock agradece e quando eles decolam diz “O vento nos levou muito longe - estamos na Rússia”. "Mas como você sabe?" Watson pergunta. "É óbvio - apenas na Rússia os codificadores pastam ovelhas", responde Sherlock. “Mas como você sabe que a garota é programadora?” - “É óbvio - ela nos deu uma resposta absolutamente precisa e totalmente inútil”.