Postgres zawiera funkcje replikacji fizycznej i logicznej. Czytaj dalej, aby dowiedzieć się więcej o różnych aspektach replikacji fizycznej.
Replikacja fizyczna
Fizyczne metody replikacji służą do przechowywania pełnej kopii wszystkich danych pojedynczego klastra (w Postgresie jest to klaster to zestaw baz danych zarządzanych przez jeden główny proces serwera Postgres o nazwie postmaster ), zwykle na innej maszynie. Maszyna źródłowa nazywa się podstawową w żargonie Postgres, a miejsce docelowe nazywa się gotowością .
Ciepłe, ciepłe i „zimne” tryby czuwania
Serwer rezerwowy, który jest utrzymywany na bieżąco z pierwotnym czasem rzeczywistym i umożliwia klientom wykonywanie transakcji tylko do odczytu, nazywa się gorącym w trybie gotowości, lub bardziej popularnie replika do odczytu . Hot standby został dodany do Postgresa w wersji 9, przed którym było tylko ciepłe czuwania. Warmstandby jest podobny do hot standby, z tym wyjątkiem, że nie pozwala klientom się z nim połączyć.
(Na marginesie:Hot standby nie może wykonywać zapytań, które tworzą tymczasowe tabele. Jest to ograniczenie Postgresa.)
„Zimna” rezerwa (nie jest to oficjalny termin) to zazwyczaj serwer rezerwowy, który nie uruchamia się do czasu przełączenia awaryjnego. Ponieważ zimny tryb gotowości nie jest uruchomiony i działa, możliwe jest, że podczas uruchamiania będzie musiał najpierw zastosować oczekujące zmiany, zanim zacznie akceptować połączenia klientów.
Pliki WAL
W normalnym toku działania serwer PostgreSQL generuje uporządkowaną serię rekordów WAL (wpisz z wyprzedzeniem). Są to w zasadzie dziennik zmian, podobny do AOF Redis lub binlog MySQL. W swej istocie replikacja fizyczna polega na przeniesieniu tych rekordów na inną maszynę i zmuszenie uruchomionego tam administratora poczty do zaakceptowania i zastosowania tych rekordów do lokalnej bazy danych.
Rekordy WAL są dzielone na pliki o jednakowej wielkości (zwykle 16 MB) zwanesegmentami WAL lub po prostu pliki WAL . Pliki te są tworzone w katalogu o nazwie pg_wal
w katalogu danych klastra (pg_wal
nazywał się pg_xlog
w wersjach Postgres przed 10). Stare pliki WAL są odrzucane, gdy nie są już potrzebne (a także w oparciu o kilka parametrów konfiguracyjnych).
Tryb odzyskiwania
Postmaster można uruchomić w trybie zwanym trybem odzyskiwania , umieszczając poprawny plik konfiguracyjny o nazwie recovery.conf w katalogu danych klastra. W trybie odzyskiwania Postgres zaimportuje i zastosuje tylko pliki WAL wygenerowane przez serwer podstawowy i sam nie wygeneruje żadnych plików WAL. Serwery działające w trybie ciepłym i gorącej gotowości działają w trybie odzyskiwania.
Po uruchomieniu w trybie odzyskiwania Postgres najpierw spróbuje zaimportować wszystkie pliki WAL dostępne w archiwum (więcej na ten temat poniżej). Gdy archiwum nie ma więcej plików WAL do zaoferowania, próbuje zaimportować wszystkie pliki leżące w pobliżu pg_wal
informator. Kiedy te też są zrobione, jeśli podstawowe połączenie jest skonfigurowane istandby_modeset na on
w pliku recovery.conf Postgres połączy się z podstawowym i pobierze i zastosuje nowe rekordy WAL, gdy zostaną utworzone w podstawowym.
Dziennik wysyłki
Wyobraź sobie, że masz wyzwalacz, który będzie wywoływany na serwerze głównym za każdym razem, gdy tworzony jest nowy plik WAL. Ten wyzwalacz może następnie skopiować nowy plik WAL do innego komputera, używając powiedzmy rsync
i umieść go w pg_wal
katalog postmasterrunning w trybie odzyskiwania. Czy możesz tak ustawić tryb gotowości?
Odpowiedź brzmi:tak i rzeczywiście była to standardowa praktyka przed dodaniem replikacji strumieniowej w Postgres v9. Ta praktyka nazywa się wysyłką dziennika .
Wyzwalaczem jest skrypt powłoki, który można skonfigurować za pomocą polecenia archive_command. Do skryptu można przekazać nazwę i ścieżkę pliku WAL.
Archiwizacja WAL
Zamiast synchronizować rsync przez plik WAL, powiedzmy, że kopiujemy go do zasobnika S3 lub katalogu zamontowanego przez NFS, który jest również dostępny z komputera rezerwowego. Ta współdzielona lokalizacja będzie teraz zawierać wszystkie pliki WAL wygenerowane przez podstawowy. staje się archiwum , a proces przechowywania plików WAL w archiwum nazywa się archiwizacją ciągłą lub po prostu archiwizacja WAL .
Odwrotność tej operacji — pobieranie plików WAL z archiwum do trybu Arecovery Postgres — można skonfigurować za pomocą polecenia restore_command. Podobnie jak w przypadku archive_command
, to również jest ścieżka do skryptu powłoki. Postmaster działający w trybie odzyskiwania wie, jakiego pliku WAL potrzebuje. Nazwa pliku może zostać przekazana do skryptu.
Jako przykład, oto polecenia archiwizacji i przywracania służące do przechowywania i pobierania plików WAL do i z zasobnika S3:
archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf
Podczas uruchamiania w trybie odzyskiwania, jeśli restore_command
jest skonfigurowany, Postgres spróbuje najpierw pobrać pliki WAL z archiwum.
pg_standby
W trybie odzyskiwania Postgres nie wie i nie może z góry wiedzieć, ile plików WAL zostało do tej pory wygenerowanych. Jeśli skonfigurowano polecenie restore_command, Postgres będzie go wielokrotnie wywoływał z progresywnymi nazwami plików WAL (nazwy są w przewidywalnej kolejności), aż polecenie zwróci błąd.
Na przykład polecenie restore mogło spełnić żądania dotyczące plików WAL000000010000000000000001
przez 00000001000000000000001A
ale nie powiedzie się dla00000001000000000000001B
ponieważ nie został znaleziony w lokalizacji archiwum. W przypadku braku plików WAL z innych źródeł, Postgres założy, że plik WAL 00000001000000000000001B
nie został jeszcze wygenerowany przez podstawowe i zakończy odzyskiwanie po zastosowaniu 00000001000000000000001A
.
Zastanów się, co się stanie, jeśli polecenie przywracania będzie czekać na plik00000001000000000000001B
być dostępny, zamiast wyjść z błędem, ponieważ nie został znaleziony. Postgres będzie nadal czekał na polecenie przywrócenia, a zatem nadal będzie w trybie odzyskiwania.
To jest poprawna konfiguracja i prawidłowy sposób na ustawienie ciepłego trybu gotowości.
Postgres jest dostarczany z poleceniem o nazwie pg_standby, którego można użyć do skonfigurowania ciepłego trybu gotowości w ten sposób, o ile archiwum jest katalogiem.pg_standby
poczeka na udostępnienie pliku, jeśli nie można go znaleźć.
Polecenia archiwizacji i przywracania za pomocą pg_standby będą wyglądać tak:
archive_command = 'cp %p /some/path/%f' # in postgresql.conf
restore_command = 'pg_standby /some/path %f %p' # in recovery.conf
Replikacja strumieniowa
Po przetworzeniu zarchiwizowanych plików WAL oraz plików w pg_wal
katalogu, Postgres może łączyć się z głównym serwerem przez sieć i wielokrotnie pobierać i stosować nowe pliki WAL podczas ich tworzenia. Ta funkcja, dodana w Postgresie 9, nazywa się replikacją strumieniową .
Serwer główny, z którym chcesz się połączyć, można określić w pliku recovery.conf:
# recovery.conf
standby_mode = on
primary_conninfo = 'host=10.0.1.10 user=repl password=p@ssw0rd'
Gorące czuwanie
Domyślnie Postgres w trybie odzyskiwania nie akceptuje połączeń klientów, odrzucając je komunikatami o błędach „baza danych jest w trybie odzyskiwania”. Dodając linię hot_standby = on
w recovery.conf możesz nawiązać połączenia klientów Postgresaccept i zezwolić im na wykonywanie transakcji tylko do odczytu:
# recovery.conf
hot_standby = on
Zwykle nie ma powodu, aby wyłączyć hot_standby.
Dokumentacja PostgreSQL zawiera więcej informacji na temat konfigurowania i uruchamiania trybu gotowości w trybie „gorącej gotowości”.
Gniazda replikacji
Sloty replikacji zostały wprowadzone w Postgresie 9.4. Są mechanizmem do dokładnego i trwałego śledzenia, jak bardzo stan gotowości pozostaje w tyle za podstawowym. Dzięki temu serwer główny może upewnić się, że pliki WAL nadal potrzebne do nadrobienia zaległości w trybie gotowości nie zostaną usunięte.
Przed gniazdami replikacji podstawa nie była w stanie tego określić, co powodowało, że rezerwa pozostawała bezczynna, ponieważ plik WAL, którego potrzebował, został usunięty przez podstawową. Oczywiście archiwa WAL mogą rozwiązać ten problem. Jednak bez archiwum WAL jedyną opcją było odbudowanie stanu gotowości ze świeżej kopii zapasowej.
Więcej informacji o slotach replikacji znajdziesz tutaj.
Kroki konfiguracji gorącej gotowości
Rzućmy okiem na kroki potrzebne do skonfigurowania gorącego czuwania dla istniejącego podstawowego.
1. Utwórz użytkownika replikacji
Najpierw potrzebujemy użytkownika do połączenia w trybie gotowości jako:
$ psql -p 6000
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.
postgres=# CREATE USER repluser REPLICATION PASSWORD 'p@ssw0rd';
CREATE USER
I odpowiednie zmiany w pg_hba.conf
:
# TYPE DATABASE USER ADDRESS METHOD
host replication repluser standby-ip/32 md5
# (replace standby-ip)
Możesz oczywiście użyć dowolnego standardowego mechanizmu uwierzytelniania PostgreSQL. Użytkownik musi mieć uprawnienia do replikacji i logowania i nie wymaga dostępu do żadnej konkretnej bazy danych.
Pamiętaj, aby ponownie załadować serwer główny, aby zmiany w pg_hba.conf miały wpływ.
2. Zrób kopię zapasową
Stan gotowości musi rozpocząć się od kopii zapasowej podstawowego. Możesz i powinieneś to zrobić za pomocą pg_basebackup
z nowym miejscem replikacji:
pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby
To łączy się z podstawowym w primary-ip:6000
z użytkownikiem, którego właśnie utworzyliśmy, i umieszcza jego kopię zapasową w katalogu standby
. Nowe gniazdo replikacjislot_standby1
jest tworzony.
3. Dodaj plik recovery.conf w trybie gotowości
Wykorzystamy to gniazdo jako nasze zapasowe gniazdo replikacji, aby zapewnić ciągłość z kopii zapasowej.
Poprosiliśmy pg_basebackup
aby utworzyć plik recovery.conf
dla nas powyżej (opcja „-R”). Spójrzmy na to:
$ cat standby/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=repluser password=''p@ssw0rd'' host=primary-ip port=6000 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_standby1'
To całkiem nieźle i nie musimy tego dalej modyfikować. Po prostu przejdźmy teraz do trybu gotowości:
o$ pg_ctl -D standby -l log_standby -o --port=6001 start
waiting for server to start.... done
server started
postgres@stg1:/tmp/demo$ cat log_standby
2019-06-19 09:17:50.032 UTC [21733] LOG: listening on IPv4 address "127.0.0.1", port 6001
2019-06-19 09:17:50.034 UTC [21733] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.6001"
2019-06-19 09:17:50.067 UTC [21734] LOG: database system was interrupted; last known up at 2019-06-19 09:12:05 UTC
2019-06-19 09:17:50.111 UTC [21734] LOG: entering standby mode
2019-06-19 09:17:50.119 UTC [21734] LOG: redo starts at 0/2000028
2019-06-19 09:17:50.120 UTC [21734] LOG: consistent recovery state reached at 0/20000F8
2019-06-19 09:17:50.120 UTC [21733] LOG: database system is ready to accept read only connections
2019-06-19 09:17:50.138 UTC [21739] LOG: started streaming WAL from primary at 0/3000000 on timeline 1
I to wszystko! Plik dziennika wskazuje, że replikacja strumieniowa jest uruchomiona. Powinieneś teraz być w stanie połączyć się z rezerwą na porcie 6001, uruchomić zapytania tylko do odczytu i zobaczyć, jak zmiany są replikowane z podstawowego mniej lub bardziej w czasie rzeczywistym.
Dalsze kroki
Dokumentacja PostgreSQL jest świetnym miejscem do dalszego zagłębiania się we wszystkie funkcje Postgresa związane z replikacją. Będziesz chciał przyjrzeć się tematom takim jak opóźniona replikacja, replikacja kaskadowa, synchroniczne tryby gotowości i nie tylko.
Chociaż Postgres ma imponujący zestaw funkcji, nadal istnieją przypadki użycia, które nie są obsługiwane. Ta strona wiki Postgres zawiera listę narzędzi innych firm, które zapewniają dodatkowe funkcje związane z replikacją.