PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Una guida a PGpool - Suggerimenti e osservazioni:parte terza

Nella parte precedente ho osato giocare con una funzionalità non implementata fantasticando su come avrebbe funzionato. Bene, HA in primo luogo è una questione di progettazione e solo successivamente di implementazione. Non giustifica una cattiva implementazione, né rende intelligente la progettazione ingenua. Tuttavia, dopo aver coperto tutti i possibili scenari e aver trovato una regola migliore adeguata per la maggior parte dei casi, a volte un piccolo cambiamento molto primitivo può rovinare la roccaforte. Di seguito voglio sandbox.

Cosa succede quando pgpool dovrebbe eseguire il failover, ma non è possibile?

Quando il controllo dello stato del master ha esito negativo, il comando failover_command viene attivato per degenerare tutto o promuovere lo slave successivo a primario. Suona solido. Cosa succede se fallisce da solo, ad esempio la connessione ssh non riesce (ad esempio perché altro - un cattivo amministratore rimuove la chiave da ~/.ssh/authorized_keys). Cosa abbiamo?

Non appena health_check_timeout (predefinito 20) è scaduto (influenzato anche da ritardo di tentativi, ritiro massimo e così via) il nodo diventa morto, quindi:

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)

Quindi non sono rimasti più tentativi e il failover non è riuscito. La prima opzione ovviamente è eseguire il failover manualmente. Ma se il failover non è riuscito a causa di qualche errore stupido, il master è tornato sui binari e l'unico problema che hai è che pgpool pensa che il master sia offline:probabilmente vorresti lasciare le cose come erano prima dell'incidente, giusto? Ovviamente non basta riportare il master online. Pgpool ha già “degenerato” il primario. Anche solo aggiungerlo come nuovo nodo non aiuterà. La cosa peggiore è che, dopo l'evento, pgpool non proverà a verificare se il vecchio master è pg_is_in_recovery() o meno, quindi non lo accetterà mai come Primario. Secondo la traccia del bug devi "Eliminare il file pgpool_status e non ripristinare lo stato precedente" con il comando pgpool -D.

Dopo aver eliminato lo stato, ci riconnettiamo per evitare che il server abbia chiuso la connessione in modo imprevisto ed eseguiamo:

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)

Tutti i nodi sono attivi e funzionanti, pgpool riconosce il master.

Infine voglio fornire alcuni suggerimenti e osservazioni sull'utilizzo di pgpool:

  • La modifica delle impostazioni del back-end è un po' complicata:nome host, porta e directory richiedono il ricaricamento per l'aggiunta di nuovi nodi, ma richiedono il riavvio per la modifica di quelli esistenti. Mentre il peso e la bandiera possono essere modificati con una semplice ricarica.

  • Non confondere i valori della colonna load_balance_node con la configurazione. Se vedi solo un nodo con true non è solo OK, è inteso così. Non significa che hai un solo nodo nel pool di bilanciamento:mostra solo quale nodo è stato scelto per questa particolare sessione. Di seguito è riportato il risultato della query con tutti e tre i nodi che partecipano al bilanciamento delle istruzioni SELECT, con l'ID nodo 2 scelto:

    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)
  • Puoi controllare quale nodo è stato scelto per il bilanciamento del carico con show pool_nodes, ma ti interessa conoscerlo per la tua query, non per quella "show", quindi tale controllo non è sempre sufficientemente informativo. Bene, puoi monitorare quale nodo usi per la query corrente, con qualcosa come:

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

Importante! Ma non:

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)

Poiché restituirà SEMPRE la porta del master. Lo stesso vale per qualsiasi pg_catalog SELECT.

  • Come hai notato nelle parti precedenti, uso un modo più complicato, rispetto a mostrare semplicemente pool_nodes per elencare i nodi con stato. Lo faccio deliberatamente per dimostrare come puoi rendere gestibile il risultato. L'uso di where rende la query più lunga, ma il risultato è chiaro, saltando tutto ciò che distrae l'attenzione per il nostro compito particolare. Confronta:

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 l'output dello spettacolo iniziale pool_nodes...

  • Non puoi confrontare pgbouncer e pgpool. Ma se lo fai, è molto importante sapere che l'analisi delle query in pgpool dipende dalla versione di pg. Pertanto, durante l'aggiornamento di PostgreSQL, è necessario aggiornare anche pgpool, mentre un'istanza di pgbouncer può avere la configurazione per 8,9,10 cluster diversi nello stesso file ini.

  • Perché non posso usare solo uno script di failover invece di pgpool? Puoi. Ma pgpool lo offre INSIEME al memcached e al pool di connessioni, al bilanciamento e al controllo del cervello diviso ed è controllato da decenni di utilizzo.

  • Il sistema di tracciamento dei bug è attivo - vale la pena visitarlo se lavori con pgpool:https://www.pgpool.net/mantisbt/my_view_page.php

  • Numerosi errori di battitura nella documentazione, come bakance (backend + bilanciamento?..), statemnet, consentito o mancata corrispondenza tra le versioni (pool_nodes erano int e ora sono enum, ma il collegamento ai vecchi valori in pcp_node-info è ancora lì) rovinano l'impressione su questo meraviglioso prodotto. Tuttavia, un modulo per inviare il rapporto sul "bug" trovato nella documentazione (proprio come "invia correzione" sui documenti postgres) lo migliorerebbe notevolmente.

  • Suggerimento importante: prima di fare affidamento su qualsiasi passaggio, controllalo. Per esempio. dopo aver promosso il nodo non puoi ripromozionarlo (qui la promozione non è un'operazione postgres, ma piuttosto la registrazione del nodo come master per 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

Suona logico e sembra fantastico. Tuttavia, se lo esegui su un nodo sbagliato (ad esempio, il nodo 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

Il che è negativo perché non puoi ripromozionare il nodo e aspettarti un errore, ma ottieni lo stato di uscita 0...

Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri ciò che devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaper

Suggerimento importante:non giocare troppo. Non giocare mai a prod!

Giocando con recovery_1st_stage_command usando pg_rewind, ho pensato di provare per curiosità un altro hack scimmia - interrogando pgpool_recovery() senza argomenti (poiché li ignoro comunque nella mia configurazione) e quindi provando semplicemente ad allegare il 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

Questa stupida idea mi ha portato 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>

Nessuna via di fuga che devo:

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

Sopra 5433 c'è la porta pgpool e 9898 è la porta pcp. Ovviamente dopo l'arresto anomalo, i file non vengono spazzati, quindi devi farlo manualmente.

  • Fai una lettura attenta e gioca molto prima di portare pgpool alla produzione. È molto più difficile trovare aiuto con pgpool quindi postgres stesso. Alcune domande non trovano mai risposta. Soprattutto quando è stato chiesto nel posto sbagliato (ho risposto in base al posto giusto per ottenere la risposta)...
  • Non dimenticare l'ultima timeline per la replica a cascata (non proprio il suggerimento di pgpool, ma spesso le persone non capiscono che per prelevare un nuovo master non è sufficiente specificare un giusto endpoint per il ricevitore).
  • L'architettura con diagramma può essere trovata qui.

Conclusione

In 10 anni sono apparse nuove promettenti funzionalità (watchdog e ip virtuale) e importanti correzioni (ad es. serialize_accept), ma nel complesso lascia un'impressione sottovalutata. I documenti hanno errori di battitura che hanno vissuto lì per 10 anni. Non credo che nessuno legga i documenti. Non credo che nessuno se ne sia accorto. Non puoi segnalarli in modo semplice. Ci sono un sacco di pistole cariche e preparate, che giacciono sul sito di documentazione per l'utente inesperto da prendere, puntare contro il piede e premere il grilletto. Non ho un'idea ragionevole di come migliorarlo, sto solo avvertendo i tiratori. Un'interpretazione errata di un parametro può metterti in una posizione disperata di reverse engineering per trovare il tuo errore. In tutti questi anni pgpool è stato e rimane una specie di prodotto per utenti avanzati. Leggendo la documentazione non ho potuto trattenermi dal ricordare la vecchia barzelletta russa su Sherlock Holmes:Sherlock e Watson volano sul pallone. Improvvisamente il forte vento li porta a migliaia di chilometri di distanza. Quando possono atterrare, vedono la ragazza che pascola le pecore. Holmes chiede alla ragazza:"Tesoro dove siamo?" e la ragazza risponde “Sei in mongolfiera!”. Sherlock ringrazia e mentre decolla dice "Il vento ci ha portato molto lontano - siamo in Russia". "Ma come fai a saperlo?" chiede Watson. "È ovvio - solo in Russia i programmatori pascolano le pecore", risponde Sherlock. "Ma come fai a sapere che la ragazza è programmatrice?" - “È ovvio - ci ha dato una risposta assolutamente precisa e del tutto inutile”.