sql >> Database >  >> RDS >> PostgreSQL

Een gids voor Pgpool voor PostgreSQL:deel twee

Dit is het tweede deel van de blog "A Guide to Pgpool for PostgreSQL". Het eerste deel over load balancing, session pooling, in memory cache en installatie vindt u hier.

Veel gebruikers kijken specifiek naar pgpool voor functies met hoge beschikbaarheid, en het heeft veel te bieden. Er zijn maar weinig instructies voor pgpool HA op het web (bijvoorbeeld een langere en een kortere), dus het heeft geen zin om ze te herhalen. We willen ook niet nog een andere blinde set configuratiewaarden bieden. In plaats daarvan stel ik voor om tegen de regels te spelen en het op de verkeerde manier te doen, dus we zullen interessant gedrag zien. Een van de meest verwachte functies (het staat in ieder geval bovenaan de pagina) is de mogelijkheid om de bruikbaarheid van een "dode" ex-master te herkennen en deze opnieuw te gebruiken met pg_rewind. Het zou uren kunnen besparen om de nieuwe stand-by met big data terug te brengen (omdat we rsync of pg_basebackup overslaan, die effectief ALLE bestanden kopieert van de nieuwe master). Strikt genomen is pg_rewind bedoeld voor geplande failover (tijdens upgrade of migratie naar nieuwe hardware). Maar we hebben gezien dat het enorm helpt met niet geplande maar toch elegante afsluiting en geautomatiseerde failover - ClusterControl maakt er bijvoorbeeld gebruik van bij het uitvoeren van automatische failover van replicatieslaves. Laten we aannemen dat we het geval hebben:we hebben (elke) master nodig om zoveel mogelijk toegankelijk te zijn. Als we om de een of andere reden (netwerkstoring, max verbindingen overschreden of een andere "fout" die het starten van nieuwe sessies verbiedt) niet langer een master kunnen gebruiken voor RW-bewerkingen, hebben we een failover-cluster geconfigureerd, met slaves die verbindingen kunnen accepteren. We kunnen dan een van de slaven promoveren en er een failover naar toe doen.

Laten we eerst aannemen dat we drie knooppunten hebben:

  • 10.1.10.124:5400 met /pg/10/m (pgpool draait hier ook)
  • 10.1.10.147:5401 met /pg/10/m2
  • 10.1.10.124:5402 met /pg/10/s2

Dat zijn in feite dezelfde nodes als in deel één, maar de failover-node wordt verplaatst naar een andere host en $PGDATA. Ik deed het om ervoor te zorgen dat ik geen typfout maakte of een extra aanhalingsteken vergat in de externe ssh-opdracht. Ook zal de foutopsporingsinformatie er eenvoudiger uitzien omdat ip-adressen anders zijn. Ten slotte wist ik niet zeker of ik deze niet-ondersteunde use-case zou kunnen laten werken, dus ik moet het met mijn eigen ogen zien.

Failover

Eerst stellen we failover_command in en voeren we pgpool reload uit en proberen we een failover uit te voeren. Hier en verder zal ik wat info naar /tmp/d op de pgpool-server herhalen, zodat ik -f /tmp/d kan volgen om de stroom te zien.

[email protected]:~$ grep failover_command /etc/pgpool2/pgpool.conf
failover_command = 'bash /pg/10/fo.sh %D %H %R'

[email protected]:~$ cat /pg/10/fo.sh
rem_cmd="pg_ctl -D $3 promote"
cmd="ssh -T [email protected]$2 $rem_cmd"
echo "$(date) $cmd" >>/tmp/d
$cmd &>>/tmp/d

NB:Heeft u $PATH ingesteld in .bashrc op een externe host?..

Laten we de meester stoppen (ik weet dat een ramp niet zo gebeurt, je verwacht op zijn minst een enorme aap of rood glanzende robot die de server met een enorme hamer kapot maakt, of in ieder geval de saaie harde schijven om te sterven, maar ik gebruik deze sierlijke variant om het mogelijke gebruik van pg_rewind te demonstreren, dus hier zal de failover het resultaat zijn van een menselijke fout of netwerkstoring een halve seconde over de health_check_periode), dus:

/usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m stop
2018-04-18 13:53:55.469 IST [27433]  LOG:  received fast shutdown request
waiting for server to shut down....2018-04-18 13:53:55.478 IST [27433]  LOG:  aborting any active transactions
2018-04-18 13:53:55.479 IST [28855] postgres t FATAL:  terminating connection due to administrator command
2018-04-18 13:53:55.483 IST [27433]  LOG:  worker process: logical replication launcher (PID 27440) exited with exit code 1
2018-04-18 13:53:55.484 IST [27435]  LOG:  shutting down
2018-04-18 13:53:55.521 IST [27433]  LOG:  database system is shut down
 done
server stopped

Controleer nu de uitvoer van de failover-opdracht:

[email protected]:~$ cat /tmp/d
Wed Apr 18 13:54:05 IST 2018 ssh -T [email protected]
pg_ctl -D /pg/10/f promote
waiting for server to promote.... done
server promoted

En na een tijdje controleren:

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 | down | standby
   1 | 5401 | up   | primary
   2 | 5402 | up   | standby
(3 rows)

Ook zien we in ex-failover clusterlogboeken:

2018-04-13 14:26:20.823 IST [20713]  LOG:  received promote request
2018-04-13 14:26:20.823 IST [20713]  LOG:  redo done at 0/951EC20
2018-04-13 14:26:20.823 IST [20713]  LOG:  last completed transaction was at log time 2018-04-13 10:41:54.355274+01
2018-04-13 14:26:20.872 IST [20713]  LOG:  selected new timeline ID: 2
2018-04-13 14:26:20.966 IST [20713]  LOG:  archive recovery complete
2018-04-13 14:26:20.998 IST [20712]  LOG:  database system is ready to accept connections

Replicatie controleren:

[email protected]:~$ psql -p 5401 t -c "select now() into test"
SELECT 1
[email protected]:~$ psql -p 5402 t -c "select * from test"
              now
-------------------------------
 2018-04-13 14:33:19.569245+01
(1 row)

De slaaf /pg/10/s2:5402 schakelde over naar een nieuwe tijdlijn dankzij recovery_target_timeline =laatste in recovery.conf, dus we zijn goed. We hoeven recovery.conf niet aan te passen om naar de nieuwe master te verwijzen, omdat het verwijst naar het pgpool-ip en de poort en ze blijven hetzelfde, ongeacht wie de primaire masterrol vervult.

Belastingverdeling controleren:

[email protected]:~$ (for i in $(seq 1 9); do psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1" -XAt; done) | sort| uniq -c
      6 5401
      3 5402

Leuk. Apps achter pgpool zullen een tweede storing opmerken en blijven werken.

Ex-meester hergebruiken

Nu kunnen we de ex-master in failover-standby zetten en terugbrengen (zonder een nieuw knooppunt aan pgpool toe te voegen, aangezien het daar al bestaat). Als je wal_log_hints of datachecksums niet hebt ingeschakeld (het uitgebreide verschil tussen deze opties vind je hier), moet je een cluster opnieuw maken op de ex-master om een ​​nieuwe tijdlijn te volgen:

[email protected]:~$ rm -fr /pg/10/m
[email protected]:~$ pg_basebackup -h localhost -p 5401 -D /pg/10/m/

Maar haast u niet om de bovenstaande uitspraken uit te voeren! Als je voorzichtig bent geweest met wal_log_hints (opnieuw opstarten vereist), kun je pg_rewind gebruiken om veel sneller over te schakelen van de ex-master naar een nieuwe slave.

Dus ATM we hebben de ex-master offline, nieuwe master met volgende tijdlijn gestart. Als de ex-master offline was vanwege een tijdelijke netwerkstoring en hij komt terug, moeten we hem eerst afsluiten. In het bovenstaande geval weten we dat het niet werkt, dus we kunnen gewoon proberen terug te spoelen:

[email protected]:~$ pg_rewind -D /pg/10/m2 --source-server="port=5401 host=10.1.10.147"
servers diverged at WAL location 0/40605C0 on timeline 2
rewinding from last common checkpoint at 0/4060550 on timeline 2
Done!

En nogmaals:

[email protected]:~$ pg_ctl -D /pg/10/m2 start
server started
...blah blah 
[email protected]:~$ 2018-04-16 12:08:50.303 IST [24699]  LOG:  started streaming WAL from primary at 0/B000000 on timeline 2

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 | down | standby
   1 | 5401 | up   | primary
   2 | 5402 | up   | standby
(3 rows)

op. Duh! Ondanks het feit dat het cluster op poort 5400 online is en een nieuwe tijdlijn volgt, moeten we pgpool vertellen om het te herkennen:

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

Nu zijn ze alle drie actief (en pgpool weet het) en synchroon:

[email protected]:~$ sql="select ts.i::timestamp(0), current_setting('data_directory'),case when pg_is_in_recovery() then 'recovering' else 'mastering' end stream from ts order by ts desc"
[email protected]:~$ psql -h 10.1.10.147 -p 5401 t -c "$sql";
          i          | current_setting |  stream
---------------------+-----------------+-----------
 2018-04-30 14:34:36 | /pg/10/m2       | mastering
(1 row)

[email protected]:~$ psql -h 10.1.10.124 -p 5402 t -c "$sql";
          i          | current_setting |   stream
---------------------+-----------------+------------
 2018-04-30 14:34:36 | /pg/10/s2       | recovering
(1 row)

[email protected]:~$ psql -h 10.1.10.124 -p 5400 t -c "$sql";
          i          | current_setting |   stream
---------------------+-----------------+------------
 2018-04-30 14:34:36 | /pg/10/m        | recovering
(1 row)

Nu probeer ik recovery_1st_stage_command te gebruiken voor het hergebruiken van ex-master:

[email protected]:~# grep 1st /etc/pgpool2/pgpool.conf
recovery_1st_stage_command = 'or_1st.sh'

Maar recovery_1st_stage_command biedt niet de benodigde argumenten voor pg_rewind, wat ik kan zien als ik aan recovery_1st_stage_command toevoeg:

echo "online recovery started on $(hostname) $(date --iso-8601) $0 $1 $2 $3 $4"; exit 1;

De uitvoer:

online recovery started on u2 2018-04-30 /pg/10/m2/or_1st.sh /pg/10/m2 10.1.10.124 /pg/10/m 5401

Nou - het gebruik van pg_rewind staat gewoon in de takenlijst - wat had ik verwacht?.. Dus ik moet een aap-hack doen om het master-ip en de poort te krijgen (onthoud dat het na een failover zal blijven veranderen).

Download de whitepaper vandaag PostgreSQL-beheer en -automatisering met ClusterControlLees wat u moet weten om PostgreSQL te implementeren, bewaken, beheren en schalenDownload de whitepaper

Een aap hack

Dus ik heb zoiets als dit in recovery_1st_stage_command:

[email protected]:~# cat /pg/10/or_1st.sh
pgpool_host=10.1.10.124
pgpool_port=5433
echo "online recovery started on $(hostname) $(date --iso-8601) $0 $1 $2 $3 $4" | ssh -T $pgpool_host "cat >> /tmp/d"
master_port=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select port from dblink('host=$pgpool_host port=$pgpool_port','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) where role='primary'")
master_host=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select hostname from dblink('host=$pgpool_host port=$pgpool_port','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) where role='primary'")
failover_host=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select hostname from dblink('host=$pgpool_host port=$pgpool_port','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) where role!='primary' order by port limit 1")
src='"port=$master_port host=$master_host"'
rem_cmd="'pg_rewind -D $3 --source-server=\"port=$master_port host=$master_host\"'"
cmd="ssh -T $failover_host $rem_cmd"
echo $cmd | ssh -T $pgpool_host "cat >> /tmp/d"
$cmd

tmp=/tmp/rec_file_tmp
cat > $tmp <<EOF
standby_mode          = 'on'
primary_conninfo      = 'host=$master_host port=$master_port user=postgres'
trigger_file = '/tmp/tg_file'
recovery_target_timeline  = latest
EOF

scp $tmp $failover_host:$3/recovery.conf

rem_cmd="pg_ctl -D $3 start"
cmd="ssh -T $failover_host $rem_cmd"
echo $cmd | ssh -T $pgpool_host "cat >> /tmp/d"
$cmd
echo "OR finished $(date --iso-8601)" | ssh -T $pgpool_host "cat >> /tmp/d"
exit 0;

Wat een rommel nu! Welnu - als u besluit een niet bestaande functie te gebruiken - bereid u voor - het ziet er slecht uit, werkt slechter en u zult zich permanent schamen voor wat u hebt gedaan. Dus stap voor stap:

  • Ik heb pgpool IP en poort nodig om er op afstand verbinding mee te maken, zowel om "show pool_nodes" op te vragen als om stappen te loggen en om commando's uit te voeren.
  • Ik stuur wat dbg-info naar /tmp/d via ssh, omdat het commando aan de masterkant wordt uitgevoerd, wat zal veranderen na een failover
  • Ik kan het resultaat van "show pool_nodes" gebruiken om de actieve hoofdverbindingsinformatie te krijgen door simpelweg te filteren met de WHERE-clausule
  • Ik heb dubbele aanhalingstekens nodig in het argument voor pg_rewind, die over ssh moet lopen, dus ik splitste het commando gewoon voor de leesbaarheid, echo het en voer het uit
  • Recovery.conf voorbereiden op basis van uitvoer van "show pool_nodes" (als ik het schrijf, vraag ik mezelf af - waarom heb ik in plaats daarvan niet gewoon pgpool IP en poort gebruikt?..
  • Nieuwe failover-slave starten (ik weet dat ik de 2e stap moet gebruiken - alleen overgeslagen om te voorkomen dat alle IP's en poort opnieuw worden gebruikt)

Wat blijft er nu over - proberen deze puinhoop in pcp te gebruiken:

[email protected]:~# pcp_recovery_node -h 127.0.0.1 -U vao -n 0 -w
pcp_recovery_node -- Command Successful
[email protected]:~# psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 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 | standby
   1 | 5401 | up | primary
   2 | 5402 | up | standby
(3 rows)

De /tmp/d op pgpool-server controleren:

[email protected]:~# cat /tmp/d
Tue May  1 11:37:59 IST 2018 ssh -T [email protected] /usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m2 promote
waiting for server to promote.... done
server promoted
online recovery started on u2 2018-05-01 /pg/10/m2/or_1st.sh /pg/10/m2
ssh -T 10.1.10.124 'pg_rewind -D --source-server="port=5401 host=10.1.10.147"'
ssh -T 10.1.10.124 pg_ctl -D start
OR finished 2018-05-01

Nu willen we het natuurlijk opnieuw rollen om te zien of het op een host werkt:

[email protected]:~$ ssh -T 10.1.10.147 pg_ctl -D /pg/10/m2 stop             waiting for server to shut down.... done
server stopped
[email protected]:~$ psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 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 | down | standby
   2 | 5402 | up   | standby
(3 rows)

[email protected]:~# pcp_recovery_node -h 127.0.0.1 -U vao -n 1 -w

[email protected]:~$ psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 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)

Logboek ziet er hetzelfde uit - alleen IP en poorten zijn gewijzigd:

 Tue May  1 11:44:01 IST 2018 ssh -T [email protected] /usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m promote
waiting for server to promote.... done
server promoted
online recovery started on u 2018-05-01 /pg/10/m/or_1st.sh /pg/10/m 10.1.10.147 /pg/10/m2 5400
ssh -T 10.1.10.147 'pg_rewind -D /pg/10/m2 --source-server="port=5400 host=10.1.10.124"'
ssh -T 10.1.10.147 pg_ctl -D /pg/10/m2 start
online recovery started on u 2018-05-01 /pg/10/m/or_1st.sh /pg/10/m
ssh -T 10.1.10.147 'pg_rewind -D --source-server="port=5400 host=10.1.10.124"'
ssh -T 10.1.10.147 pg_ctl -D start
OR finished 2018-05-01

In deze sandbox verhuisde de master naar 5401 bij failover en na daar een tijdje te hebben gewoond, ging hij terug naar 5400. Het gebruik van pg_rewind zou het zo snel mogelijk moeten maken. Voorheen was het enge deel van automatische failover - als je de configuratie echt verknoeide en geen overmacht had voorzien, kon je automatische failover tegenkomen naar de volgende slave en de volgende en volgende totdat er geen vrije slave meer over is. En daarna heb je gewoon meerdere split-brained-masters en geen failover-reserve. Het is een schrale troost in een dergelijk scenario om nog meer slaves te hebben voor failover, maar zonder pg_rewind zou je zelfs dat niet hebben. "Traditionele" rsync of pg_basebackup kopieer ALLE $PGDATA om een ​​stand-by te maken en kan de "niet te veel verschillende" ex-master niet opnieuw gebruiken.

Ter afsluiting van dit experiment wil ik nogmaals benadrukken dat dit geen oplossing is die geschikt is voor blind copy-pasten. Het gebruik van pg_rewind wordt niet aangemoedigd voor pg_pool. Het is niet bruikbaar bij alle ATM. Ik wilde wat frisse lucht toevoegen aan de pgpool HA-configuratie, zodat nubes zoals ik een beetje beter konden zien hoe het werkt. Voor coryphaeus om te glimlachen bij naïvistische benadering en het misschien met onze nubes-ogen te zien.


  1. Hoe het MySQL-rootwachtwoord opnieuw in te stellen

  2. Hoe u Change Data Capture (CDC) op een database in SQL Server inschakelt - SQL Server-zelfstudie

  3. Zoeken in Microsoft Access-gegevens met Elasticsearch

  4. De voordelen van MariaDB's Certified Associate-programma ontsluiten