V předchozím díle jsem si troufl pohrát si s neimplementovanou funkcí a fantazírovat, jak to bude fungovat. No HA na prvním místě je věcí návrhu a teprve potom implementace. To neomlouvá špatnou implementaci, ani to dělá naivní design vypadat chytře. Ale poté, co pokryjete všechny možné scénáře a najdete adekvátní nejlepší pravidlo pro většinu případů, může někdy velmi primitivní malá změna zničit pevnost. Níže chci sandbox.
Co se stane, když by měl pgpool přejít po selhání, ale nemůže?
Když kontrola stavu selže u hlavního serveru, spustí se příkaz failover_command, aby zdegeneroval všechny nebo povýšil dalšího slave na primární. Zní to solidně. Co když to samo selže, např. selže připojení ssh (např. protože jiný - špatný administrátor odstraní klíč z ~/.ssh/authorized_keys). Co máme?
Jakmile health_check_timeout (výchozí 20) vyprší (také ovlivněno zpožděním opakování, maximálním vyřazením atd.), uzel se stane mrtvým, takže:
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)
Nezbývá tedy žádné opakování a převzetí služeb při selhání se nezdařilo. První možností je samozřejmě ruční převzetí služeb při selhání. Ale pokud selhalo selhání kvůli nějaké hloupé chybě, master je zpět na kolejích a jediný problém, který máte, je, že si pgpool myslí, že master je offline – pravděpodobně byste místo toho chtěli nechat věci tak, jak bývaly před nehodou – že? Pouhé přesunutí mistra zpět online samozřejmě nestačí. Pgpool již „degeneroval“ primární. Pouhé přidání jako nového uzlu také nepomůže. Nejhorší je, že po události se pgpool nepokusí zkontrolovat, zda starý master je pg_is_in_recovery() nebo ne, takže ho nikdy nepřijme jako primární. Podle bug tracku musíte „Zahodit soubor pgpool_status a neobnovovat předchozí stav“ pomocí příkazu pgpool -D.
Po zrušení stavu se znovu připojíme, abychom se vyhnuli tomu, že server neočekávaně ukončil připojení a spustil:
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)
Všechny uzly jsou zpět v provozu a pgpool rozpozná master.
Nakonec chci uvést několik rad a postřehů k používání pgpool:
-
Změna nastavení backendu je trochu ošemetná:název hostitele, port a adresář vyžadují opětovné načtení pro přidání nových uzlů, ale vyžadují restart pro úpravu stávajících. Zatímco hmotnost a vlajku lze změnit pouhým načtením.
-
Nezaměňujte hodnoty sloupce load_balance_node s konfigurací. Pokud vidíte jen jeden uzel s true, není to jen v pořádku – je to tak myšleno. Neznamená to, že máte pouze jeden uzel ve vyrovnávacím fondu – pouze ukazuje, který uzel je vybrán pro tuto konkrétní relaci. Níže je uveden výsledek dotazu se všemi třemi uzly účastnícími se vyvažování příkazů SELECT, s vybraným ID uzlu 2:
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)
-
Můžete zkontrolovat, který uzel byl vybrán pro vyrovnávání zátěže, pomocí show pool_nodes, ale záleží vám na tom, abyste to věděli pro svůj dotaz, ne ten „show“, takže taková kontrola není vždy dostatečně informativní. Můžete sledovat, který uzel používáte pro aktuální dotaz, pomocí něčeho jako:
t=# select *,current_setting('port') from now(); now | current_setting -------------------------------+----------------- 2018-04-09 13:56:17.501779+01 | 5401 (1 row)
Důležité! Ale ne:
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)
Protože VŽDY vrátí mistrův port. Totéž platí pro jakýkoli SELECT.
-
Jak jste si všimli v předchozích dílech, pro výpis uzlů se stavem používám složitější způsob, než jen ukázat pool_nodes. Dělám to záměrně, abych ukázal, jak můžete dosáhnout toho, aby byl výsledek zvládnutelný. Použitím příkazu where je dotaz delší, ale výsledek je jasný a přeskakuje vše, co odvádí pozornost od našeho konkrétního úkolu. Porovnejte:
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
S výstupem počáteční show pool_nodes...
-
Nemůžete srovnávat pgbouncer a pgpool. Ale pokud ano, nejdůležitější je vědět, že analýza dotazů v pgpool závisí na verzi pg. Takže když upgradujete postgreSQL, musíte upgradovat také pgpool, zatímco jedna instance pgbouncer může mít konfiguraci pro 8,9,10 různých clusterů ve stejném ini souboru.
-
Proč nemohu místo pgpool použít pouze skript pro přepnutí při selhání? Můžeš. Ale pgpool to nabízí SOUČASNĚ s memcached a sdružováním připojení a vyvažováním a rozděleným ovládáním mozku a je prověřeno desetiletími používání.
-
Systém sledování chyb je na místě – stojí za to ho navštívit, pokud pracujete s pgpool:https://www.pgpool.net/mantisbt/my_view_page.php
-
Četné překlepy v dokumentaci, jako je bakance (backend + zůstatek?..), Statemnet, povoleno nebo nesoulad napříč verzí (pool_nodes bývaly int a nyní jsou enum, ale odkaz na staré hodnoty v pcp_node-info je stále tam) kazí dojem na tomto úžasném produktu. Formulář pro odeslání hlášení o nalezené „chybě“ v dokumentaci (stejně jako „odeslat opravu“ v dokumentech postgres) by to však výrazně zlepšil.
-
Důležitý tip: než se spolehnete na jakýkoli krok - zkontrolujte to. Např. po propagaci uzlu jej nemůžete znovu propagovat (zde propagace není postgresová operace, ale spíše registrace uzlu jako hlavního pro 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
Zní to logicky a vypadá to skvěle. Pokud to však spustíte proti nesprávnému uzlu (např. uzel 0 je ! 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
Což je špatné, protože nemůžete znovu propagovat uzel a očekávat chybu, ale dostanete stav ukončení 0…
Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si WhitepaperDůležitý tip:Nehrajte příliš mnoho. Nikdy nehrajte na prod!
Když jsem si hrál s recovery_1st_stage_command pomocí pg_rewind, napadlo mě ze zvědavosti zkusit další opičí hack - dotazování pgpool_recovery() bez argumentů (protože je stejně ignoruji v nastavení) a pak se jen pokusit připojit uzel k 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
Tento hloupý nápad mě přivedl k:
[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>
Nemám únik, musím:
[email protected]:~# kill -9
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.5433
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.9898
Nad 5433 je port pgpool a 9898 je port pcp. Je zřejmé, že po havárii nejsou soubory smeteny, takže to musíte udělat ručně.
- Před uvedením pgpool do produkce si pozorně přečtěte a hodně si hrajte. Je mnohem těžší najít pomoc s pgpool než samotný postgres. Některé otázky nejsou nikdy zodpovězeny. Zvláště když jsem se zeptal na špatném místě (odpověděl jsem na správném místě, abych dostal odpověď)...
- Nezapomeňte na nejnovější časovou osu pro kaskádovou replikaci (ve skutečnosti to není rada pgpool, ale lidé často nechápou, že k vyzvednutí nového masteru nestačí určit správný koncový bod pro přijímač). li>
- Architekturu s diagramem lze nalézt zde.
Závěr
Za 10 let se objevily nové slibné funkce (watchdog a virtuální ip) a důležité opravy (např. serialize_accept), ale celkově to zanechává podhodnocený dojem. Dokumenty mají překlepy, které tam žijí 10 let. Nevěřím, že dokumenty nikdo nečte. nevěřím, že si toho nikdo nevšiml. Nemůžete je jednoduše nahlásit. Na místě dokumentace je spousta nabitých a připravených zbraní, které si začínající uživatel může vzít, namířit proti noze a stisknout spoušť. Nemám rozumnou představu, jak to zlepšit - jen varuji střelce. Špatná interpretace jednoho parametru vás může uvrhnout do zoufalé pozice reverzního inženýrství, abyste našli svou chybu. Všechny ty roky pgpool býval a zůstává druhem produktu pro pokročilé uživatele. Při čtení dokumentace Nemohl jsem si nevzpomenout na starý ruský vtip o Sherlocku Holmesovi:Sherlock a Watson létají na balónu. Najednou je silný vítr odvál tisíce kilometrů daleko. Když mohou přistát, vidí dívku pást ovce. Holmes se ptá dívky:"Miláčku, kde to jsme?" a dívka odpoví:"Jste na balónu!". Sherlock děkuje a když vzlétají, říká „Vítr nás zanesl velmi daleko – jsme v Rusku“. "Ale jak to víš?" ptá se Watson. "Je to zřejmé - pouze v Rusku kodéři pasou ovce," odpovídá Sherlock. "Ale jak víš, že ta dívka je kodér?" - "To je zřejmé - dala nám naprosto přesnou a naprosto zbytečnou odpověď."