PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Przewodnik po PGpool — wskazówki i obserwacje:część trzecia

W poprzedniej części odważyłem się pobawić nie zaimplementowaną funkcją, fantazjując, jak to działa. Cóż, HA na pierwszym miejscu to kwestia projektu, a dopiero potem wdrożenia. Nie usprawiedliwia złej implementacji, ani nie sprawia, że ​​naiwne projektowanie wygląda elegancko. Jednak po omówieniu wszystkich możliwych scenariuszy i znalezieniu odpowiedniej najlepszej reguły dla większości przypadków, czasami bardzo prymitywna mała zmiana może zrujnować twierdzę. Poniżej chcę piaskownicy.

Co się stanie, gdy pgpool powinien przełączyć się w tryb awaryjny, ale nie może?

Gdy kontrola kondycji nie powiedzie się dla urządzenia głównego, polecenie failover_command jest uruchamiane w celu zdegenerowania wszystkich lub awansowania następnego urządzenia podrzędnego do podstawowego. Brzmi solidnie. Co jeśli samo się zawiedzie, np. połączenie ssh nie powiedzie się (np. ponieważ inny - zły administrator usunął klucz z ~/.ssh/authorized_keys). Co mamy?

Gdy tylko health_check_timeout (domyślnie 20) zostanie wyłączone (wpływ na to również opóźnienie ponownych prób, maksymalna liczba wycofywania itd.), węzeł przestaje działać, więc:

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)

Więc nie ma ponownych prób i przełączenie awaryjne nie powiodło się. Pierwsza opcja to oczywiście ręczne przełączanie awaryjne. Ale jeśli przełączanie awaryjne nie powiodło się z powodu jakiegoś głupiego błędu, master jest znowu na szynach, a jedynym problemem, jaki masz, jest myślenie, że master jest offline – prawdopodobnie chciałbyś zamiast tego zostawić rzeczy tak, jak były przed wypadkiem – prawda? Oczywiście samo przeniesienie mistrza z powrotem do trybu online nie wystarczy. Pgpool już „zdegenerował” główny. Samo dodanie go jako nowego węzła też nie pomoże. Najgorsze jest to, że po zdarzeniu pgpool nie będzie próbował sprawdzić, czy stary master to pg_is_in_recovery(), czy nie, dlatego nigdy nie zaakceptuje go jako podstawowego. Zgodnie ze ścieżką błędów musisz „Odrzuć plik pgpool_status i nie przywracaj poprzedniego stanu” za pomocą polecenia pgpool -D.

Po odrzuceniu statusu łączymy się ponownie, aby uniknąć sytuacji, w której serwer nieoczekiwanie zamyka połączenie i uruchamiamy:

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)

Wszystkie węzły są zarchiwizowane i działają, pgpool rozpoznaje mastera.

Na koniec chcę omówić kilka wskazówek i obserwacji dotyczących korzystania z pgpool:

  • Zmiana ustawień zaplecza jest trochę trudna:nazwa hosta, port i katalog wymagają przeładowania w celu dodania nowych węzłów, ale wymagają ponownego uruchomienia w celu edycji istniejących. Podczas gdy wagę i flagę można zmienić, wystarczy przeładować.

  • Nie myl wartości kolumny load_balance_node z konfiguracją. Jeśli widzisz tylko jeden węzeł z prawdą, to nie jest po prostu w porządku – to oznacza, że ​​tak. Nie oznacza to, że masz tylko jeden węzeł w puli bilansującej - pokazuje tylko, który węzeł jest wybrany do tej konkretnej sesji. Poniżej znajduje się wynik zapytania ze wszystkimi trzema węzłami uczestniczącymi w równoważeniu instrukcji SELECT, z wybranym identyfikatorem węzła 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)
  • Możesz sprawdzić, który węzeł został wybrany do równoważenia obciążenia za pomocą polecenia show pool_nodes, ale zależy Ci na tym, aby znać go w zapytaniu, a nie „pokaż”, więc takie sprawdzenie nie zawsze jest wystarczająco pouczające. Cóż, możesz monitorować, którego węzła używasz dla bieżącego zapytania, na przykład:

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

Ważny! Ale nie:

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)

Ponieważ ZAWSZE zwróci port kapitana. To samo dotyczy każdego WYBORU pg_catalog.

  • Jak zauważyłeś w poprzednich częściach, używam bardziej skomplikowanego sposobu, niż po prostu pokaż pool_nodes, aby wyświetlić węzły ze stanem. Robię to celowo, aby zademonstrować, jak można sprawić, by wynik był wykonalny. Użycie where powoduje wydłużenie zapytania, ale wynik jest jasny, pomijając wszystko, co rozprasza uwagę na naszym konkretnym zadaniu. Porównaj:

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

Z wyjściem początkowego show pool_nodes...

  • Nie możesz porównać pgbouncera i pgpool. Ale jeśli tak, najważniejsze, aby wiedzieć, że parsowanie zapytań w pgpool zależy od wersji pg. Tak więc podczas aktualizacji postgreSQL musisz również zaktualizować pgpool, podczas gdy jedna instancja pgbouncer może mieć konfigurację dla 8,9,10 różnych klastrów w tym samym pliku ini.

  • Dlaczego nie mogę użyć tylko skryptu awaryjnego zamiast pgpool? Możesz. Ale pgpool oferuje to RAZEM z memcached i łączeniem połączeń oraz równoważeniem i podzieloną kontrolą mózgu i jest sprawdzane przez dziesięciolecia użytkowania.

  • System śledzenia błędów jest na miejscu - warto go odwiedzić, jeśli pracujesz z pgpool:https://www.pgpool.net/mantisbt/my_view_page.php

  • Liczne literówki w dokumentacji, takie jak bakance (backend + balance?..), statemnet, allow lub niezgodność w różnych wersjach (kiedyś pool_nodes było int, a teraz są enum, ale link do starych wartości w pcp_node-info wciąż tam jest) psuje wrażenie na tym wspaniałym produkcie. Formularz do wysłania raportu o znalezionym „błądzie” w dokumentacji (podobnie jak „prześlij korektę” w dokumentach postgres) znacznie go poprawi.

  • Ważna wskazówka: zanim zaczniesz polegać na jakimkolwiek kroku - sprawdź to. Np. po wypromowaniu węzła nie można go ponownie promować (tutaj promowanie nie jest działaniem postgres, a raczej rejestracją węzła jako master dla 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

Brzmi logicznie i świetnie wygląda. Jeśli jednak uruchomisz to przeciwko niewłaściwemu węzłowi (np. węzeł 0 to ! 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 jest złe, ponieważ nie możesz ponownie promować węzła i oczekiwać błędu, ale otrzymujesz status wyjścia 0…

Pobierz oficjalny dokument już dziś Zarządzanie i automatyzacja PostgreSQL za pomocą ClusterControlDowiedz się, co musisz wiedzieć, aby wdrażać, monitorować, zarządzać i skalować PostgreSQLPobierz oficjalny dokument

Ważna wskazówka:nie graj za dużo. Nigdy nie graj w programie!

Bawiąc się z recovery_1st_stage_command za pomocą pg_rewind, pomyślałem z ciekawości, żeby spróbować innego małpiego hacka - odpytywanie pgpool_recovery() bez argumentów (ponieważ i tak je ignoruję w mojej konfiguracji), a następnie po prostu próbuję dołączyć węzeł do 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

Ten głupi pomysł doprowadził mnie do:

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

Nie muszę uciekać:

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

Powyżej 5433 to port pgpool, a 9898 to port pcp. Oczywiście po awarii pliki nie są usuwane, więc musisz to zrobić ręcznie.

  • Przeczytaj uważnie i baw się dużo, zanim uruchomisz pgpool. Znacznie trudniej jest znaleźć pomoc dotyczącą pgpool niż samego postgresa. Na niektóre pytania nie ma odpowiedzi. Zwłaszcza, gdy zostałem zapytany w niewłaściwym miejscu (odpowiedziałem na podstawie właściwego miejsca, aby uzyskać odpowiedź)...
  • Nie zapomnij o najnowszym harmonogramie replikacji kaskadowej (nie jest to wskazówka dotycząca pgpool, ale często ludzie nie rozumieją, że w celu pobrania nowego mastera nie wystarczy określić właściwy punkt końcowy dla odbiorcy).
  • Architektura ze schematem można znaleźć tutaj.

Wniosek

W ciągu 10 lat pojawiły się nowe obiecujące funkcje (watchdog i wirtualne IP) oraz ważne poprawki (np. serialize_accept), ale ogólnie pozostawia to niedoceniane wrażenie. Dokumenty mają literówki, które mieszkają tam od 10 lat. Nie wierzę, że nikt nie czyta dokumentów. Nie wierzę, że nikt tego nie zauważył. Po prostu nie możesz ich zgłosić w łatwy sposób. Na stronie z dokumentacją znajduje się mnóstwo załadowanych i przygotowanych broni, które początkujący użytkownik może wziąć, wycelować w stopę i pociągnąć za spust. Nie mam rozsądnego pomysłu, jak to poprawić - tylko ostrzegam strzelców. Błędna interpretacja jednego parametru może postawić Cię w desperackiej pozycji inżynierii wstecznej, aby znaleźć swój błąd. Przez te wszystkie lata pgpool był i pozostaje rodzajem produktu dla zaawansowanych użytkowników. Czytając dokumentację nie mogłem się powstrzymać od przypomnienia starego rosyjskiego żartu o Sherlocku Holmesie:Sherlock i Watson latają balonem. Nagle silny wiatr zdmuchuje ich tysiące mil dalej. Kiedy mogą wylądować, widzą dziewczynę pasącą owce. Holmes pyta dziewczynę:„Kochanie, gdzie jesteśmy?” a dziewczyna odpowiada „Jesteś na balonie!”. Sherlock dziękuje i jak odlatują mówi „Wiatr zabrał nas bardzo daleko – jesteśmy w Rosji”. „Ale skąd wiesz?” – pyta Watson. „To oczywiste – tylko w Rosji koderzy pasą owce” – odpowiada Sherlock. „Ale skąd wiesz, że dziewczyna jest programistką?” - „To oczywiste – udzieliła nam absolutnie dokładnej i całkowicie bezużytecznej odpowiedzi”.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL Reverse LIKE

  2. Jak najlepiej wykorzystać indeksy PostgreSQL

  3. Klauzula SQL Between z kolumnami stringów

  4. PostgreSQL - maksymalna liczba parametrów w klauzuli IN?

  5. PostgreSQL:Wybierz dane z podobnym do pola znacznika czasu