sql >> Database >  >> RDS >> PostgreSQL

Een gids voor PGpool - Hints en observaties:deel drie

In het vorige deel durfde ik te spelen met een niet geïmplementeerde feature en fantaseerde hoe het zou werken. Welnu, HA op de eerste plaats is een kwestie van ontwerp en pas daarna implementatie. Het is geen excuus voor slechte implementatie, en het maakt naïef ontwerpen ook niet slim. Maar nadat je alle mogelijke scenario's hebt behandeld en een adequate beste regel hebt gevonden voor de meeste gevallen, kan soms een zeer primitieve kleine verandering het bolwerk ruïneren. Hieronder wil ik sandboxen.

Wat gebeurt er als pgpool zou moeten failover, maar niet kan?

Wanneer de statuscontrole mislukt voor de master, wordt het failover_command afgevuurd om alles te degenereren of de volgende slave naar primair te promoveren. Klinkt solide. Wat als het zelf faalt, bijv. ssh-verbinding mislukt (bijv. omdat andere - slechte admin-sleutel verwijdert van ~/.ssh/authorized_keys). Wat hebben we?

Zodra health_check_timeout (standaard 20) uit is (ook beïnvloed door vertraging bij opnieuw proberen, max met pensioen enzovoort), wordt het knooppunt dood, dus:

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)

Dus geen nieuwe pogingen meer over en de failover is mislukt. De eerste optie is uiteraard om de failover handmatig uit te voeren. Maar als failover mislukt vanwege een stomme fout, is master weer op de rails, en het enige probleem dat je hebt is dat pgpool denkt dat de master offline is - je zou waarschijnlijk de dingen willen laten zoals ze waren voor het ongeluk - toch? Alleen master terug online zetten is natuurlijk niet genoeg. Pgpool heeft de primaire al "ontaard". Gewoon toevoegen als een nieuw knooppunt zal ook niet helpen. Het ergste is dat pgpool na de gebeurtenis niet zal proberen te controleren of de oude master pg_is_in_recovery() is of niet, en het dus nooit als primair zal accepteren. Volgens de bugtrack moet je "Pgpool_status-bestand weggooien en de vorige status niet herstellen" met het pgpool -D-commando.

Nadat we de status hebben verwijderd, maken we opnieuw verbinding om te voorkomen dat de server de verbinding onverwachts heeft verbroken en voeren we het volgende uit:

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)

Alle nodes zijn weer actief, pgpool herkent de master.

Tot slot wil ik wat hints en observaties geven over het gebruik van pgpool:

  • Het wijzigen van de backend-instellingen is een beetje lastig:hostnaam, poort en directory moeten opnieuw worden geladen om nieuwe knooppunten toe te voegen, maar moeten opnieuw worden opgestart voor het bewerken van bestaande. Terwijl het gewicht en de vlag kunnen worden gewijzigd door gewoon opnieuw te laden.

  • Verwar load_balance_node kolomwaarden niet met configuratie. Als je slechts één knooppunt met waar ziet, is dat niet alleen OK - het is zo bedoeld. Het betekent niet dat u slechts één knooppunt in de balanceringspool hebt - het laat alleen zien welk knooppunt is gekozen voor deze specifieke sessie. Hieronder ziet u het queryresultaat waarbij alle drie de knooppunten deelnemen aan SELECT-instructies, waarbij knooppunt-ID 2 is gekozen:

    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)
  • U kunt controleren welk knooppunt is gekozen voor taakverdeling met show pool_nodes, maar u wilt het graag weten voor uw zoekopdracht, niet voor de "show", dus een dergelijke controle is niet altijd informatief genoeg. Welnu, je kunt controleren welk knooppunt je gebruikt voor de huidige query, met zoiets als:

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

Belangrijk! Maar niet:

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)

Omdat het ALTIJD de poort van de meester zal retourneren. Hetzelfde geldt voor elke pg_catalog SELECT.

  • Zoals je in eerdere delen hebt opgemerkt, gebruik ik een meer gecompliceerde manier dan alleen pool_nodes te tonen om knooppunten met status weer te geven. Ik doe het bewust om te laten zien hoe je het resultaat beheersbaar kunt maken. Als u waar gebruikt, wordt de zoekopdracht langer, maar het resultaat duidelijk, en wordt alles overgeslagen dat de aandacht voor onze specifieke taak afleidt. Vergelijk:

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

Met de uitvoer van de eerste show pool_nodes...

  • Je kunt pgbouncer en pgpool niet vergelijken. Maar als u dat doet, is het belangrijk om te weten dat het parseren van query's in pgpool afhankelijk is van de pg-versie. Dus bij het upgraden van postgreSQL, moet u ook pgpool upgraden, terwijl één pgbouncer-instantie config kan hebben voor 8,9,10 verschillende clusters in hetzelfde ini-bestand.

  • Waarom kan ik niet alleen een failover-script gebruiken in plaats van pgpool? Jij kan. Maar pgpool biedt het SAMEN met memcached en connectie pooling en balancering en split brain control en wordt gecontroleerd door tientallen jaren van gebruik.

  • Bug Tracking-systeem is aanwezig - het is de moeite waard om het te bezoeken als u met pgpool werkt:https://www.pgpool.net/mantisbt/my_view_page.php

  • Talloze typefouten in documentatie, zoals bakance (backend + balance?..), statemnet, allowd of mismatch over versie (pool_nodes waren vroeger int en zijn nu enum, maar link naar oude waarden in pcp_node-info is er nog steeds) bederft de indruk op dit prachtige product. Een formulier om het rapport over gevonden "bug" in documentatie te verzenden (net als "correctie indienen" op postgres-documenten) zou het echter aanzienlijk verbeteren.

  • Belangrijke tip: voordat u op een stap vertrouwt - controleer deze. bijv. na het promoten van node kun je het niet opnieuw promoten (hier is promoten geen postgres-bewerking, maar eerder registratie van het knooppunt als master voor 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

Klinkt logisch en ziet er goed uit. Maar als u dit tegen het verkeerde knooppunt uitvoert (bijv. knooppunt 0 is ! 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

Wat slecht is, want je kunt node niet opnieuw promoten en een fout verwachten, maar je krijgt exit-status 0...

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

Belangrijke tip:speel niet te veel. Speel nooit op prik!

Spelend met recovery_1st_stage_command met pg_rewind, dacht ik om uit nieuwsgierigheid een andere aap-hack te proberen - pgpool_recovery() opvragen zonder argumenten (omdat ik ze sowieso negeer in mijn setup) en dan gewoon proberen de node aan pgpool te koppelen:

[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

Dit stomme idee bracht me tot:

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

Ik hoef niet te ontsnappen:

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

Boven 5433 is pgpool-poort en 9898 is pcp-poort. Uiteraard worden bestanden na een crash niet geveegd, dus u moet dit handmatig doen.

  • Lees aandachtig en speel veel voordat je pgpool in productie neemt. Het is veel moeilijker om hulp te vinden bij pgpool dan bij Postgres zelf. Sommige vragen worden nooit beantwoord. Vooral wanneer het op de verkeerde plaats wordt gevraagd (ik beantwoordde het op basis van de juiste plaats om het antwoord te krijgen)...
  • Vergeet de laatste tijdlijn voor trapsgewijze replicatie niet (niet echt de pgpool-hint, maar vaak begrijpen mensen niet dat om een ​​nieuwe master op te halen, het niet voldoende is om een ​​juist eindpunt voor de ontvanger te specificeren).
  • li>
  • Architectuur met diagram is hier te vinden.

Conclusie

In 10 jaar verschenen nieuwe veelbelovende functies (watchdog en virtueel ip) en belangrijke fixes (bijv. serialize_accept), maar over het algemeen laat het een ondergewaardeerde indruk achter. Documenten hebben typefouten die daar al 10 jaar staan. Ik geloof niet dat niemand de documenten leest. Ik geloof niet dat het niemand is opgevallen. Je kunt ze gewoon niet zomaar melden. Er zijn genoeg geweren geladen en voorbereid, liggend op de documentatiesite voor de beginnende gebruiker om te nemen, tegen de voet te wijzen en de trekker over te halen. Ik heb geen redelijk idee hoe ik het kan verbeteren - ik waarschuw alleen de schutters. Het verkeerd interpreteren van één parameter kan u in een wanhopige positie van reverse engineering brengen om uw fout te vinden. Al die jaren was en blijft pgpool een soort product voor gevorderde gebruikers. Documentatie lezend Ik kon het niet helpen dat ik me de oude Russische grap over Sherlock Holmes niet herinnerde:Sherlock en Watson vliegen op de ballon. Plots blaast de sterke wind hen duizenden mijlen weg. Als ze kunnen landen, zien ze het meisje schapen grazen. Holmes vraagt ​​het meisje:"Lieveling waar zijn we?" en het meisje antwoordt "Je zit op de ballon!". Sherlock bedankt en terwijl ze opstijgen zegt "De wind heeft ons heel ver gebracht - we zijn in Rusland". "Maar hoe weet je dat?" vraagt ​​Watson. "Het is duidelijk - alleen in Rusland grazen codeurs schapen", antwoordt Sherlock. "Maar hoe weet je dat het meisje codeur is?" - "Het is duidelijk - ze gaf ons een absoluut nauwkeurig en totaal nutteloos antwoord".


  1. Tabel vastzetten in de Flash-cache

  2. NLS_NUMERIC_CHARACTERS instelling voor decimaal

  3. Gebruik T-SQL en retourneer het n-de gescheiden element van een string

  4. Proactief verzamelen van informatie over fragmentatie van SQL Server-indexen