sql >> Databasteknik >  >> RDS >> PostgreSQL

En guide till PGpool - Tips och observationer:del tre

I förra delen vågade jag leka med en icke implementerad funktion som fantiserade hur det skulle fungera. Jo HA i första hand är en fråga om design och först därefter implementering. Det ursäktar inte dålig implementering, det får inte heller naiv design att se smart ut. Men efter att du täckt alla möjliga scenarier och hittat en adekvat bästa regel för de flesta fall, kan ibland en mycket primitiv liten förändring förstöra fästet. Nedan vill jag sandboxa.

Vad händer när pgpool skulle fallera, men inte kan?

När hälsokontrollen misslyckas för mastern avfyrades failover_kommandot för att degenerera alla eller främja nästa slav till primär. Låter solidt. Tänk om det misslyckas själv, t.ex. ssh-anslutningen misslyckas (t.ex. för att annan - dålig admin tar bort nyckel från ~/.ssh/authorized_keys). Vad har vi?

Så fort health_check_timeout (standard 20) är ute (påverkas också av fördröjning om ett nytt försök, max går i pension och så vidare) blir noden död, så:

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)

Så inga återförsök kvar och failover misslyckades. Det första alternativet är uppenbarligen att göra failover manuellt. Men om failover misslyckades på grund av något dumt fel, är master tillbaka på spåren, och det enda problemet du har är att pgpool tror att mastern är offline - du skulle förmodligen vilja lämna saker som de brukade vara innan olyckan istället - eller hur? Det räcker såklart inte att bara flytta master tillbaka online. Pgpool har redan "degenererat" den primära. Att bara lägga till det som en ny nod hjälper inte heller. Det värsta är att pgpool efter händelsen inte kommer att försöka kontrollera om den gamla mastern är pg_is_in_recovery() eller inte, och kommer därför aldrig att acceptera den som primär. Enligt felspår måste du "Kassera filen pgpool_status och inte återställa tidigare status" med kommandot pgpool -D.

Efter att ha ignorerat statusen återansluter vi för att undvika att servern stängde anslutningen oväntat och kör:

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)

Alla noder är igång igen, pgpool känner igen mastern.

Slutligen vill jag täcka några tips och observationer om hur man använder pgpool:

  • Att ändra backend-inställningar är lite knepigt:värdnamn, port och katalog kräver omladdning för att lägga till nya noder, men kräver omstart för att redigera befintliga. Medan vikt och flagga kan ändras genom att bara ladda om.

  • Blanda inte ihop load_balance_node kolumnvärden med konfiguration. Om du bara ser en nod med sant är det inte bara OK - det är menat så. Det betyder inte att du bara har en nod i balanseringspoolen - det visar bara vilken nod som är vald för just denna session. Nedan visas frågeresultat med alla tre noder som deltar i SELECT-satsbalansering, med nod-id 2 valt:

    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)
  • Du kan kontrollera vilken nod som valdes för lastbalansering med show pool_nodes, men du bryr dig om att känna till den för din fråga, inte "show", så en sådan kontroll är inte alltid tillräckligt informativ. Du kan övervaka vilken nod du använder för den aktuella frågan, med något som:

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

Viktig! Men inte:

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)

Eftersom det ALLTID kommer att returnera befälhavarens hamn. Detsamma gäller för alla pg_catalog SELECT.

  • Som du märkte i tidigare delar använder jag ett mer komplicerat sätt än att bara visa pool_nodes för att lista noder med tillstånd. Jag gör det medvetet för att visa hur du kan göra resultatet hanterbart. Att använda where gör frågan längre, men resultatet tydligt, och hoppar över allt som distraherar uppmärksamheten för just vår uppgift. Jämför:

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

Med utdata från initial show pool_nodes...

  • Du kan inte jämföra pgbouncer och pgpool. Men om du gör det är det viktigast att veta att analys av frågor i pgpool beror på pg-versionen. Så när du uppgraderar postgreSQL måste du också uppgradera pgpool, medan en pgbouncer-instans kan ha konfiguration för 8,9,10 olika kluster i samma ini-fil.

  • Varför kan jag inte bara använda ett failover-skript istället för pgpool? Du kan. Men pgpool erbjuder det TILLSAMMANS med memcachad och anslutningspoolning och balansering och delad hjärnkontroll och kontrolleras av årtionden av användning.

  • Buggspårningssystem är på plats - värt att besöka det om du arbetar med pgpool:https://www.pgpool.net/mantisbt/my_view_page.php

  • Många stavfel i dokumentationen, som bakance (backend + balans?..), statemnet, tillåten eller oöverensstämmelse mellan versioner (pool_nodes brukade vara int och nu är enum, men länken till gamla värden i pcp_node-info finns kvar) förstör intrycket på denna underbara produkt. Ett formulär för att skicka rapporten om hittat "bugg" i dokumentationen (precis som "skicka in korrigering" på postgres docs) skulle dock förbättra det avsevärt.

  • Viktigt tips: innan du förlitar dig på något steg - kontrollera det. T.ex. efter att ha marknadsfört noden kan du inte marknadsföra den igen (här är marknadsföring inte postgres-operation, utan snarare registrering av noden som master för 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

Låter logiskt och ser bra ut. Men om du kör detta mot fel nod (t.ex. nod 0 är ! 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

Vilket är dåligt eftersom du inte kan repromovera noden och förvänta dig ett fel, men du får utgångsstatus 0...

Ladda ner Whitepaper Today PostgreSQL Management &Automation med ClusterControlLäs om vad du behöver veta för att distribuera, övervaka, hantera och skala PostgreSQLDladda Whitepaper

Viktigt tips:Spela inte för mycket. Spela aldrig på prod!

När jag lekte med recovery_1st_stage_command med pg_rewind, tänkte jag testa av nyfikenhet ett annat monkey hack - fråga pgpool_recovery() utan argument (som jag ignorerar dem i min uppsättning ändå) och sedan bara försöka koppla noden till 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

Denna dumma idé förde mig till:

[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>

Ingen flykt jag måste:

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

Ovanför 5433 är pgpool-port och 9898 är pcp-port. Uppenbarligen svepas inte filer efter kraschen, så du måste göra det manuellt.

  • Läs noga och spela mycket innan du tar pgpool till produktion. Det är mycket svårare att hitta hjälp med pgpool än postgres själv. Vissa frågor besvaras aldrig. Speciellt när jag frågade på fel ställe (jag svarade på rätt ställe för att få svaret)...
  • Glöm inte den senaste tidslinjen för kaskadreplikering (inte riktigt pgpool-tipset, men ofta förstår folk inte att det inte räcker med att ange en rätt slutpunkt för mottagaren för att kunna hämta en ny master).
  • Arkitektur med diagram kan hittas här.

Slutsats

På 10 år dök det upp nya lovande funktioner (watchdog och virtuell ip) och viktiga korrigeringar (t.ex. serialize_accept), men totalt sett lämnar det ett undervärderat intryck. Doc har stavfel som har bott där i 10 år. Jag tror inte att ingen läser dokumenten. Jag tror inte att ingen märkte det. Du kan bara inte rapportera dem på något enkelt sätt. Det finns massor av vapen laddade och förberedda, liggande på dokumentationsplatsen för nybörjaren att ta, peka mot foten och trycka på avtryckaren. Jag har ingen rimlig aning om hur jag ska förbättra det - jag varnar bara skyttarna. Att feltolka en parameter kan kasta dig i en desperat position av omvänd ingenjörskonst för att hitta ditt misstag. Alla dessa år pgpool brukade vara och förblir en typ av produkt för avancerade användare. När jag läste dokumentationen kunde jag inte låta bli att minnas det gamla ryska skämtet om Sherlock Holmes:Sherlock och Watson flyger på ballongen. Plötsligt blåser den starka vinden dem tusentals mil bort. När de kan landa ser de flickan som betar får. Holmes frågar flickan:"Älskling var är vi?" och flickan svarar "Du är på ballongen!". Sherlock tackar och när de lyfter säger "Vinden tog oss väldigt långt - vi är i Ryssland". "Men hur vet du det?" frågar Watson. "Det är uppenbart - bara i Ryssland betar kodare får" svarar Sherlock. "Men hur vet du att flickan är kodare?" - "Det är uppenbart - hon gav oss ett absolut exakt och totalt värdelöst svar".


  1. Kontrollera om en tabell har en främmande nyckel i SQL Server med OBJECTPROPERTY()

  2. Övervaka sidans förväntade livslängd i SQL Server

  3. Prestanda för SQL Server 2005 Query

  4. Procedur för att exportera tabell till flera csv-filer