Doszło jednak do awarii i musimy dać użytkownikom naszego systemu możliwość zmian danych - czyli musimy zmienić działanie naszego standby na działającego primary i przekierować cały ruch na ten serwer.
Niestety PostgreSQL nie ma oprogramowania do identyfikacji crashu mastera i automatycznego promowania slava. Musimy zrobić to ręcznie (Na szczęście są narzędzia, które mogą nam w tym pomóc).
W poniższym przykładzie mamy dwie działające instancje na tej samej maszynie. Master pracuje na standardowym porcie, czyli 5432, a slave na porcie 6432. Sprawdźmy je aby mieć pewność, że działają tak jak chcemy:
[root@amsterdam /var/lib/pgsql]$ psql test psql (9.3.5) Wpisz "help" by uzyskać pomoc. test=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- f (1 wiersz) test=# select name, setting from pg_settings where name = 'port'; name | setting ------+--------- port | 5432 (1 wiersz) test=# \q [root@amsterdam /var/lib/pgsql]$ psql -p6432 test psql (9.3.5) Wpisz "help" by uzyskać pomoc. test=# select name, setting from pg_settings where name = 'port'; name | setting ------+--------- port | 6432 (1 wiersz) test=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- t (1 wiersz)
Jedenym ze sposobów inicjonowania procesu failover, jest dodanie do pliku recovery.conf informacji o pliku triggera:
[root@amsterdam /var/lib/pgsql/9.3/data4]$ cat recovery.done standby_mode = 'on' primary_conninfo = 'user=replication password=replication host=127.0.0.1 port=5432 sslmode=prefer sslcompression=1 krbsrvname=postgres' trigger_file = '/var/lib/pgsql/psql.trigger.6432'
Zawartość pliku triggera ma znaczenie. Jeśli jest pusta lub zawiera słowo 'smart', standby zostanie podniesiony zaraz po zatwierdzeniu wszystkich dostępnych w katalogu archive plików WAL (Smart Failover). Jeśli jednak zawartość pliku będzie zawierać słowo 'fast', serwer ma zostać podniesiony natychmiast. Wszystkie pliki WAL, które nie zostały jeszcze zastosowane, będą ignorowane, a transakcję w nich zostaną utracone (Fast Failover).
Spróbujmy uruchomić proces Smart Failover:
[root@amsterdam /var/lib/pgsql]$ touch /var/lib/pgsql/psql.trigger.6432 [root@amsterdam /var/lib/pgsql]$ ll 9.3/data4/ razem 112 -rw------- 1 postgres postgres 208 09-25 05:09 backup_label.old drwx------ 6 postgres postgres 4096 09-25 05:09 base drwx------ 2 postgres postgres 4096 09-25 05:38 global drwx------ 2 postgres postgres 4096 09-25 05:09 pg_clog -rw------- 1 postgres postgres 4309 09-25 05:09 pg_hba.conf -rw------- 1 postgres postgres 1636 09-25 05:09 pg_ident.conf drwx------ 2 postgres postgres 4096 09-25 05:36 pg_log drwx------ 4 postgres postgres 4096 09-25 05:09 pg_multixact drwx------ 2 postgres postgres 4096 09-25 05:36 pg_notify drwx------ 2 postgres postgres 4096 09-25 05:09 pg_serial drwx------ 2 postgres postgres 4096 09-25 05:09 pg_snapshots drwx------ 2 postgres postgres 4096 09-25 05:09 pg_stat drwx------ 2 postgres postgres 4096 09-25 05:39 pg_stat_tmp drwx------ 2 postgres postgres 4096 09-25 05:09 pg_subtrans drwx------ 2 postgres postgres 4096 09-25 05:09 pg_tblspc drwx------ 2 postgres postgres 4096 09-25 05:09 pg_twophase -rw------- 1 postgres postgres 4 09-25 05:09 PG_VERSION drwx------ 3 postgres postgres 4096 09-25 05:39 pg_xlog -rw------- 1 postgres postgres 20573 09-25 05:11 postgresql.conf -rw------- 1 postgres postgres 60 09-25 05:36 postmaster.opts -rw------- 1 postgres postgres 74 09-25 05:36 postmaster.pid -rw-r--r-- 1 postgres postgres 208 09-25 05:18 recovery.done [root@amsterdam /var/lib/pgsql]$ psql -p6432 test psql (9.3.5) Wpisz "help" by uzyskać pomoc. test=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- f (1 wiersz) test=# select name, setting from pg_settings where name = 'port'; name | setting ------+--------- port | 6432 (1 wiersz) test=# \qSerwer działający w trybie 'recovery mode' został tak zaprojektowany, aby odtwarzać dane po nieoczekiwanym zamknięciu. Plik recovery.conf definiuje jak znaleźć pliki logów transakcji i trzymać je dopóki nie są nam potrzebne. Wtedy serwer przechodzi w tryb normalny i sam generuje własne pliki logów transakcji. Gdy ten proces zostaje zakończony (failover), nazwa plik recovery.conf jest zmieniana na recovery.done.
Innym sposobem na promowanie slava na mastera, bez użycia pliku triggera, jest uruchomienie programu pg_ctl promote. Jako parametr podajemy katalog instancji slava (musimy to zrobić użytkownikiem nieuprzywilejowanym, który będzie właścicielem procesu):
[root@amsterdam /var/lib/pgsql/9.3]$ sudo su postgres bash-4.2$ bash-4.2$ cd bash-4.2$ /usr/pgsql-9.3/bin/pg_ctl promote -D /var/lib/pgsql/9.3/data5 serwer w trakcie rozgłaszania bash-4.2$ bash-4.2$ psql -p6432 test psql (9.3.5) Wpisz "help" by uzyskać pomoc. test=# select name, setting from pg_settings where name = 'port'; name | setting ------+--------- port | 6432 (1 wiersz) test=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- f (1 wiersz) test=# \q
Widziałam wiele zapytań o automatyzację tego procesu na różnych forach internetowych. Pytanie jest tylko takie - czy jesteśmy w stanie napisać skrypt, który podjoł by decyzję, że serwer primary padł i aby system miał działać nadal musimy promować standby na jego miejsce? A może to był tylko problem sieciowy i niedługo wszystko wróci do normy. Czy nie lepiej aby to człowiek zdecydował, aby proces promowania rozpocząć i sam proces failover automatyzować.
Powodzenia i miłego testowania działania replikacji.