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

Korzystanie z gniazd replikacji PostgreSQL

Co to są przedziały replikacji?

W czasach, gdy „Gniazda replikacji” nie zostały jeszcze wprowadzone, zarządzanie segmentami WAL było wyzwaniem. W standardowej replikacji strumieniowej master nie ma wiedzy o statusie slave. Weźmy przykład mastera, który wykonuje dużą transakcję, podczas gdy węzeł gotowości jest w trybie konserwacji przez kilka godzin (np. aktualizacja pakietów systemowych, dostosowanie zabezpieczeń sieci, aktualizacja sprzętu itp.). W pewnym momencie master usuwa swój dziennik transakcji (segmenty WAL) po przejściu przez punkt kontrolny. Gdy niewolnik jest wyłączony z konserwacji, prawdopodobnie ma ogromne opóźnienie niewolników i musi dogonić pana. W końcu niewolnik otrzyma fatalny problem, taki jak poniżej:

LOG:  started streaming WAL from primary at 0/73000000 on timeline 1

FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000000000073 has already been removed

Typowym podejściem jest określenie w pliku postgresql.conf skryptu archiwalnego WAL, który będzie kopiował pliki WAL do jednej lub więcej lokalizacji archiwów długoterminowych. Jeśli nie masz żadnych klientów w trybie gotowości ani innych klientów replikacji strumieniowej, w zasadzie serwer może odrzucić plik WAL, gdy skrypt archiwum zostanie wykonany lub zareaguje poprawnie. Ale nadal będziesz potrzebować niektórych najnowszych plików WAL do odzyskiwania po awarii (dane z ostatnich plików WAL są odtwarzane podczas odzyskiwania po awarii. W naszym przykładzie węzła gotowości, który jest umieszczony na długi okres konserwacji, problemy pojawiają się, gdy wraca on do trybu online i pyta podstawowy dla pliku WAL, którego podstawowy już nie ma, wówczas replikacja nie powiedzie się.

Ten problem został rozwiązany w PostgreSQL 9.4 przez „Gniazda replikacji”.

Jeśli nie używasz gniazd replikacji, powszechnym sposobem zmniejszenia ryzyka niepowodzenia replikacji jest ustawienie wal_keep_segments na wystarczająco wysokim poziomie, aby pliki WAL, które mogą być potrzebne, nie były obracane ani poddawane recyklingowi. Wadą tego podejścia jest to, że trudno jest określić, jaka wartość jest najlepsza dla twojej konfiguracji. Nie będziesz potrzebować codziennej konserwacji lub nie będziesz musiał przechowywać dużego stosu plików WAL, który pochłania pamięć dyskową. Chociaż to działa, nie jest to idealne rozwiązanie, ponieważ ryzykowanie miejsca na dysku na dysku głównym może spowodować niepowodzenie przychodzących transakcji.

Alternatywne podejście do nieużywania gniazd replikacji polega na skonfigurowaniu PostgreSQL z ciągłą archiwizacją i udostępnieniu polecenia restore_command, aby dać replice dostęp do archiwum. Aby uniknąć gromadzenia się WAL na podstawowym, możesz użyć oddzielnego woluminu lub urządzenia magazynującego dla plików WAL, np. SAN lub NFS. Inną rzeczą jest replikacja synchroniczna, ponieważ wymaga ona, aby podstawowy musiał czekać, aż węzły rezerwowe zatwierdzą transakcję. Oznacza to, że zapewnia, że ​​pliki WAL zostały zastosowane do węzłów rezerwowych. Mimo to najlepiej jest zapewnić archiwizację poleceń z poziomu podstawowego, aby po ponownym uruchomieniu WAL w podstawowym, mieć pewność, że masz kopie zapasowe WAL na wypadek odzyskania. Chociaż w niektórych sytuacjach replikacja synchroniczna nie jest idealnym rozwiązaniem, ponieważ wiąże się z pewnym obciążeniem wydajnościowym w porównaniu z replikacją asynchroniczną.

Typy przedziałów replikacji

Istnieją dwa rodzaje gniazd replikacji. Są to:

Fizyczne gniazda replikacji

Może być używany do standardowej replikacji strumieniowej. Zadbają o to, aby dane nie były przetwarzane zbyt wcześnie.

Gniazda replikacji logicznej

Replikacja logiczna wykonuje to samo, co fizyczne szczeliny replikacji i jest używana do replikacji logicznej. Są jednak używane do logicznego dekodowania. Ideą dekodowania logicznego jest umożliwienie użytkownikom dołączenia do dziennika transakcji i odszyfrowania go za pomocą wtyczki. Pozwala wyodrębnić zmiany dokonane w bazie danych, a tym samym w dzienniku transakcji w dowolnym formacie i w dowolnym celu.

W tym blogu będziemy używać fizycznych gniazd replikacji i jak to osiągnąć za pomocą ClusterControl.

Zalety i wady korzystania z gniazd replikacji

Gniazda replikacji są zdecydowanie korzystne po włączeniu. Domyślnie „Gniazda replikacji” nie są włączone i należy je ustawić ręcznie. Wśród zalet korzystania z gniazd replikacji są

  • Zapewnia, że ​​master zachowuje wystarczającą liczbę segmentów WAL, aby wszystkie repliki mogły je otrzymać
  • Uniemożliwia urządzeniu głównemu usuwanie wierszy, które mogłyby spowodować konflikt odzyskiwania w replikach
  • Master może odtworzyć dziennik transakcji tylko wtedy, gdy zostanie on wykorzystany przez wszystkie repliki. Zaletą jest to, że niewolnik nigdy nie może pozostać w tyle, aby potrzebna była ponowna synchronizacja.

Gniazda replikacji mają również pewne zastrzeżenia.

  • Osierocony slot replikacji może powodować nieograniczony wzrost dysku z powodu nagromadzenia plików WAL z mastera
  • Węzły podrzędne poddane długiej konserwacji (takiej jak dni lub tygodnie) i powiązane z gniazdem replikacji będą miały nieograniczony wzrost dysku z powodu nagromadzenia plików WAL z urządzenia głównego

Możesz to monitorować, wysyłając zapytanie do pg_replication_slots, aby określić, które sloty nie są używane. Sprawdzimy to nieco później.

Korzystanie z przedziałów replikacji

Jak wspomniano wcześniej, istnieją dwa rodzaje gniazd replikacji. W tym blogu użyjemy fizycznych gniazd replikacji do replikacji strumieniowej.

Tworzenie gniazda replikacji

Tworzenie replikacji jest proste. W tym celu należy wywołać istniejącą funkcję pg_create_physical_replication_slot, którą należy uruchomić i utworzyć w węźle głównym. Funkcja jest prosta,

maximus_db=# \df pg_create_physical_replication_slot

Schema              | pg_catalog

Name                | pg_create_physical_replication_slot

Result data type    | record

Argument data types | slot_name name, immediately_reserve boolean DEFAULT false, OUT slot_name name, OUT xlog_position pg_lsn

Type                | normal

np. Tworzenie miejsca replikacji o nazwie gniazdo1,

postgres=# SELECT pg_create_physical_replication_slot('slot1');

-[ RECORD 1 ]-----------------------+---------

pg_create_physical_replication_slot | (slot1,)

Nazwy gniazd replikacji i ich podstawowa konfiguracja dotyczą tylko całego systemu, a nie klastra. Na przykład, jeśli masz węzeł A (bieżący główny) i węzły rezerwowe nodeB i nodeC, tworząc gniazdo w węźle głównym, a mianowicie „slot1”, dane nie będą dostępne dla węzła B i węzła C. Dlatego też, gdy ma nastąpić przełączenie awaryjne/przełączanie, musisz ponownie utworzyć utworzone sloty.

Upuszczanie gniazda replikacji

Nieużywane miejsca replikacji muszą zostać usunięte lub usunięte. Jak wspomniano wcześniej, jeśli istnieją osierocone gniazda replikacji lub gniazda, które nie zostały przypisane do żadnych węzłów klienckich lub rezerwowych, ich pozostawienie może prowadzić do nieograniczonych problemów z miejscem na dysku. Dlatego bardzo ważne jest, aby je usunąć, gdy nie są już używane. Aby go usunąć, po prostu wywołaj pg_drop_replication_slot. Ta funkcja ma następującą definicję:

maximus_db=# \df pg_drop_replication_slot

Schema              | pg_catalog

Name                | pg_drop_replication_slot

Result data type    | void

Argument data types | name

Type                | normal

Upuszczenie jest proste:

maximus_db=# select pg_drop_replication_slot('slot2');

-[ RECORD 1 ]------------+-

pg_drop_replication_slot |

Monitorowanie slotów replikacji PostgreSQL

Monitorowanie gniazd replikacji to coś, czego nie chcesz przegapić. Po prostu zbierz informacje z widoku pg_replication_slots w węźle głównym/głównym, tak jak poniżej:

postgres=# select * from pg_replication_slots;

-[ RECORD 1 ]-------+-----------

slot_name           | main_slot

plugin              |

slot_type           | physical

datoid              |

database            |

active              | t

active_pid          | 16297

xmin                |

catalog_xmin        |

restart_lsn         | 2/F4000108

confirmed_flush_lsn |

-[ RECORD 2 ]-------+-----------

slot_name           | main_slot2

plugin              |

slot_type           | physical

datoid              |

database            |

active              | f

active_pid          |

xmin                |

catalog_xmin        |

restart_lsn         |

confirmed_flush_lsn |

Powyższy wynik pokazuje, że zajęto main_slot, ale nie main_slot2.

Kolejną rzeczą, jaką możesz zrobić, jest monitorowanie opóźnienia w stosunku do posiadanych slotów. Aby to osiągnąć, możesz po prostu użyć zapytania na podstawie przykładowego wyniku poniżej:

postgres=# SELECT redo_lsn, slot_name,restart_lsn, 

round((redo_lsn-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

redo_lsn    | slot_name | restart_lsn | gb_behind 

------------+-----------+-------------+-----------

 1/8D400238 |     slot1 | 0/9A000000 | 3.80

Ale redo_lsn nie jest obecny w 9.6, powinien używać redo_location, więc w 9.6,

imbd=# SELECT redo_location, slot_name,restart_lsn, 

round((redo_location-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

-[ RECORD 1 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

-[ RECORD 2 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot2

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

Wymagania dotyczące zmiennych systemowych

Implementacja przedziałów replikacji wymaga ręcznego ustawienia. Istnieją zmienne, o których należy pamiętać, które wymagają zmian i które należy określić w pliku postgresql.conf. Zobacz poniżej:

  • max_replication_slots — Jeśli jest ustawiony na 0, oznacza to, że sloty replikacji są całkowicie wyłączone. Jeśli używasz wersji PostgreSQL <10, to gniazdo musi być określone inaczej niż 0 (domyślnie). Od PostgreSQL 10 wartością domyślną jest 10. Ta zmienna określa maksymalną liczbę gniazd replikacji. Ustawienie go na niższą wartość niż liczba aktualnie istniejących gniazd replikacji uniemożliwi uruchomienie serwera.
  • wal_level – musi być co najmniej repliką lub wyższą (replika jest domyślna). Ustawienie hot_standby lub archiwum spowoduje odwzorowanie na replikę. W przypadku fizycznego gniazda replikacji wystarczy replika. W przypadku logicznych gniazd replikacji preferowana jest logika.
  • max_wal_senders – domyślnie ustawione na 10, 0 w wersji 9.6, co oznacza, że ​​replikacja jest wyłączona. Sugerujemy ustawienie tego na co najmniej 16, szczególnie podczas pracy z ClusterControl.
  • hot_standby – w wersjach <10 należy ustawić to na, które jest domyślnie wyłączone. Jest to ważne dla węzłów gotowości, co oznacza, że ​​gdy są włączone, możesz łączyć się i uruchamiać zapytania podczas odzyskiwania lub w trybie gotowości.
  • nazwa_slotu_podstawowego –  ta zmienna jest ustawiana przez plik recovery.conf w węźle gotowości. Jest to gniazdo używane przez odbiorcę lub węzeł gotowości podczas łączenia się z nadawcą (lub głównym/głównym).

Musisz pamiętać, że te zmienne wymagają głównie ponownego uruchomienia usługi bazy danych w celu ponownego załadowania nowych wartości.

Korzystanie z gniazd replikacji w środowisku ClusterControl PostgreSQL

Teraz zobaczmy, jak możemy wykorzystać fizyczne sloty replikacji i zaimplementować je w konfiguracji Postgres zarządzanej przez ClusterControl.

Wdrażanie węzłów bazy danych PostgreSQL

Zacznijmy tym razem wdrażanie 3-węzłowego klastra PostgreSQL przy użyciu ClusterControl i wersji PostgreSQL 9.6.

ClusterControl wdroży węzły z następującymi zmiennymi systemowymi zdefiniowanymi odpowiednio na podstawie ich wartości domyślnych lub dostrojone wartości. W:

postgres=# select name, setting from pg_settings where name in ('max_replication_slots', 'wal_level', 'max_wal_senders', 'hot_standby');

         name          | setting 

-----------------------+---------

 hot_standby           | on

 max_replication_slots | 0

 max_wal_senders       | 16

 wal_level             | replica

(4 rows)

W wersjach PostgreSQL> 9.6, domyślną wartością max_replication_slots jest 10, która jest domyślnie włączona, ale nie w wersji 9.6 lub niższych, która jest domyślnie wyłączona. Musisz przypisać max_replication_slots większe niż 0. W tym przykładzie ustawiłem max_replication_slots na 5.

[email protected]:~# grep 'max_replication_slots' /etc/postgresql/9.6/main/postgresql.conf 

# max_replication_slots = 0                     # max number of replication slots

max_replication_slots = 5

i ponownie uruchomił usługę,

[email protected]:~# pg_lsclusters 

Ver Cluster Port Status Owner    Data directory Log file

9.6 main    5432 online postgres /var/lib/postgresql/9.6/main pg_log/postgresql-%Y-%m-%d_%H%M%S.log



[email protected]:~# pg_ctlcluster 9.6 main restart

Ustawianie przedziałów replikacji dla węzłów głównych i rezerwowych

ClusterControl nie ma takiej opcji, aby to zrobić, więc musisz ręcznie utworzyć swoje sloty. W tym przykładzie utworzyłem gniazda w głównym w hoście 192.168.30.100:

192.168.10.100:5432 [email protected]_db=# SELECT pg_create_physical_replication_slot('slot1'), pg_create_physical_replication_slot('slot2');

 pg_create_physical_replication_slot | pg_create_physical_replication_slot 

-------------------------------------+-------------------------------------

 (slot1,)                            | (slot2,)

(1 row)

Sprawdzam, co właśnie stworzyliśmy,

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | f      | | |       | | 

 slot2     | | physical  | | | f      | | |       | | 

(2 rows)

Teraz w węzłach gotowości musimy zaktualizować plik recovery.conf i dodać zmienną nazwa_głównego_slotu oraz zmienić nazwę_aplikacji, aby łatwiej było zidentyfikować węzeł. Oto jak to wygląda w hoście 192.168.30.110 recovery.conf:

[email protected]:/var/lib/postgresql/9.6/main/pg_log# cat ../recovery.conf 

standby_mode = 'on'

primary_conninfo = 'application_name=node11 host=192.168.30.100 port=5432 user=cmon_replication password=m8rLmZxyn23Lc2Rk'

recovery_target_timeline = 'latest'

primary_slot_name = 'slot1'

trigger_file = '/tmp/failover_5432.trigger'

Robiąc to samo na hoście 192.168.30.120, ale zmieniłem nazwę_aplikacji i ustawiłem primary_slot_name ='slot2'.

Sprawdzanie stanu gniazda replikacji:

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | t      | 24252 | |       | 0/CF0A4218 | 

 slot2     | | physical  | | | t      | 11635 | |       | 0/CF0A4218 | 

(2 rows)

Czego jeszcze potrzebujesz?

Ponieważ ClusterControl nie obsługuje obecnie gniazd replikacji, należy wziąć pod uwagę pewne kwestie. Co to jest? Przejdźmy do szczegółów.

Proces przełączania awaryjnego/przełączania

Gdy podjęto próbę automatycznego przełączenia awaryjnego lub przełączenia za pośrednictwem ClusterControl, gniazda nie zostaną zachowane z węzłów podstawowych i rezerwowych. Musisz odtworzyć to ręcznie, sprawdzić zmienne, jeśli są ustawione poprawnie, i odpowiednio zmodyfikować plik recovery.conf.

Odbudowa Slave z Master

Podczas odbudowywania slave'a, recovery.conf nie zostanie zachowany. Oznacza to, że ustawienia recovery.conf mające nazwę primary_slot_name zostaną usunięte. Musisz określić to ponownie ręcznie i sprawdzić widok pg_replication_slots, aby określić, czy sloty są prawidłowo używane, czy też zostały porzucone.

Jeśli chcesz odbudować węzeł podrzędny/wstrzymany z głównego, być może będziesz musiał rozważyć określenie zmiennej env PGAPPNAME, tak jak w poniższym poleceniu:

$ export PGAPPNAME="app_repl_testnode15"; /usr/pgsql-9.6/bin/pg_basebackup -h 192.168.10.190 -U cmon_replication -D /var/lib/pgsql/9.6/data -p5434 -W -S main_slot -X s -R -P

Określenie parametru -R jest bardzo ważne, więc spowoduje ponowne utworzenie pliku recovery.conf, podczas gdy -S określi nazwę gniazda, która ma być użyta podczas odbudowy węzła rezerwowego.

Wnioski

Implementacja slotów replikacji w PostgreSQL jest prosta, ale istnieją pewne zastrzeżenia, o których musisz pamiętać. Podczas wdrażania z ClusterControl będziesz musiał zaktualizować niektóre ustawienia podczas przełączania awaryjnego lub przebudowy urządzenia podrzędnego.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak używać dynamicznych nazw kolumn w instrukcji UPDATE lub SELECT w funkcji?

  2. Co zrobić z wartościami null podczas modelowania i normalizacji?

  3. Dlaczego iteracja przez duży Django QuerySet zużywa ogromne ilości pamięci?

  4. Przegląd nowych procedur składowanych w PostgreSQL 11

  5. Wyodrębnij datę (rrrr/mm/dd) ze znacznika czasu w PostgreSQL