Ponieważ coraz więcej postów na temat PostgreSQL 11 pojawia się w sieci, tym bardziej nieaktualne może się wydawać korzystanie z Postgres 9. Chociaż wydanie wersji PostgreSQL 10 wydarzyło się zaledwie kilka miesięcy temu, ludzie już mówią o kolejnej wersji. Rzeczy się poruszają, więc nie chcesz pozostać w tyle. Na tym blogu omówimy, co musisz wiedzieć, aby uaktualnić do najnowszej wersji Postgres 10.
Opcje aktualizacji
Pierwszą rzeczą, o której powinieneś wiedzieć przed rozpoczęciem, jest to, że istnieje kilka sposobów przeprowadzenia aktualizacji:
- Tradycyjny pg_dumpall(pg_dump) / pg_restore(psql)
- Tradycyjna aktualizacja pg_upgrade
- Replikacja oparta na wyzwalaczach (Slony, napisana samodzielnie)
- Korzystanie z replikacji pglogicznej
Dlaczego istnieje taka różnorodność? Ponieważ każda z nich ma inną historię, wymagającą innych wysiłków i oferowania innych usług. Przyjrzyjmy się każdemu z nich.
Tradycyjny zrzut/przywrócenie
pg_dump t > /tmp/f
psql -p 5433 -f /tmp/f
Tradycyjne usuwanie/przywracanie zajmuje najwięcej czasu, a mimo to jest często popularnym wyborem dla tych, którzy mogą sobie pozwolić na przestój. Po pierwsze, wystarczy wykonać logiczną kopię zapasową i przywrócić ją do nowej, wyższej wersji bazy danych. Można powiedzieć, że tak naprawdę nie jest to aktualizacja, ponieważ „importujesz” swoje dane do „nowej struktury”. W rezultacie otrzymasz dwie konfiguracje - jedną starą (niższą wersję) i nowo zaktualizowaną. Jeśli proces przywracania zakończy się bez błędu, jesteś prawie na miejscu. Jeśli nie, musisz zmodyfikować istniejący stary klaster, aby wyeliminować wszelkie błędy i rozpocząć proces od nowa.
Jeśli używasz psql do importu, być może będziesz musiał samodzielnie utworzyć kilka wstępnie załadowanych skryptów do wykonania w nowej konfiguracji przed migracją. Na przykład, chciałbyś wykonać pg_dumpall -g, aby uzyskać listę potrzebnych ról do przygotowania w nowej konfiguracji, lub odwrotnie uruchomić pg_dump -x, aby pominąć uprawnienia ze starego. Ten proces jest dość prosty w przypadku małych baz danych, złożoność rośnie wraz z rozmiarem i złożonością struktury bazy danych i zależy od skonfigurowanych funkcji. Zasadniczo, aby ta metoda odniosła sukces, musisz próbować i naprawiać, aż aktualizacja się powiedzie.
Zalety korzystania z tej metody obejmują...
- Chociaż możesz spędzić dużo czasu z jedną utworzoną kopią zapasową – obciążenie starego serwera jest tak małe, jak zrobienie jednej kopii zapasowej.
- Ta metoda to w większości sekwencja przywracania kopii zapasowej (potencjalnie z niektórymi zaklęciami, piosenkami i bębnieniem)
- Korzystanie z tej metody jest najstarszym sposobem na uaktualnienie i zostało zweryfikowane przez WIELE osób
Kiedy w końcu zakończysz aktualizację, musisz albo zamknąć stary serwer, albo zaakceptować utratę danych (lub alternatywnie odtworzyć DML, który miał miejsce na starym serwerze podczas przywracania kopii zapasowej na nowym serwerze). A czas poświęcony na to jest zależny od rozmiaru Twojej bazy danych.
Możesz oczywiście zacząć "korzystać" z nowej bazy danych przed zakończeniem przywracania (zwłaszcza przed zbudowaniem wszystkich indeksów - często najwięcej czasu zajmuje indeksowanie). Niemniej jednak takie przestoje są często niedopuszczalne.
Tradycyjna aktualizacja pg_upgrade
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/initdb -D tl0 >/tmp/suppressing_to_save_screen_space_read_it
WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/pg_upgrade -b /usr/local/Cellar/postgresql/9.5.3/bin -B /usr/local/Cellar/postgresql/10.2/bin -d t -D tl0 | tail
Creating script to delete old cluster ok
Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
./analyze_new_cluster.sh
Running this script will delete the old cluster’s data files:
./delete_old_cluster.sh
Tradycyjny pg_upgrade został stworzony, aby skrócić czas potrzebny na aktualizację do głównej wersji. W zależności od ilości relacji, jakie masz, może to trwać zaledwie kilka minut (sekundy w śmiesznych przypadkach, takich jak jedna tabela w bazie danych i godziny w „przeciwnych przypadkach”), zwłaszcza z argumentem --link.
Sekwencja przygotowań różni się nieco od pierwszej metody aktualizacji. Aby zaprojektować uaktualnienie, a tym samym sprawdzić, czy jest to możliwe, należy zbudować replikację strumieniową lub odzyskać serwer rezerwowy z WAL-ów. Dlaczego to takie skomplikowane? Chcesz mieć pewność, że uaktualnienie zostanie przetestowane w bazie danych o stanie zbliżonym do stanu pierwotnego. Pomoże nam tutaj replikacja „binarna” lub PITR. Po zakończeniu odzyskiwania i recovery_target_action =prom (PITR) lub promowaniu nowo zbudowanego slave (pg_ctl promuj lub umieść plik wyzwalacza) (replikacja strumieniowa) możesz spróbować uruchomić pg_upgrade. Sprawdzenie pg_upgrade_internal.log da ci wyobrażenie, czy proces się powiódł, czy nie. Co więcej, masz takie samo podejście „próbuj i napraw”, jak w poprzedniej metodzie. Zapisujesz działania podjęte na testowej bazie danych w skrypcie, dopóki nie zostanie pomyślnie pg_upgrade. Ponadto możesz zniszczyć niepotrzebny już test zaktualizowana baza danych, uruchom zapisany skrypt, aby przygotować oryginalną bazę danych do przeprowadzenia aktualizacji.
Zalety korzystania z tej metody obejmują…
- Krótszy czas przestoju niż logiczny backup/przywracanie
- Zgrabny proces - pg_upgrade aktualizuje oryginalną bazę danych o istniejące dane i strukturę
- Był często używany w przeszłości i nadal byłby preferowany dla większości DBA działających w wersji poniżej 9.4 (co pozwala na używanie pgLogic)
Wady korzystania z tej metody obejmują…
- Wymaga przestoju
Replikacja oparta na wyzwalaczach
Zakładając, że wersja 10 jest na porcie 5433 i ma przygotowaną taką samą tabelę:
db=# create server upgrade_to_10 foreign data wrapper postgres_fdw options (port '5433', dbname 'dbl0');
CREATE SERVER
Time: 9.135 ms
db=# create user mapping for vao SERVER upgrade_to_10 options (user 'vao');
CREATE USER MAPPING
Time: 8.741 ms
db=# create foreign table rl0 (pk int, t text) server upgrade_to_10 options (table_name 'r');
CREATE FOREIGN TABLE
Time: 9.358 ms
Jest to niezwykle uproszczona funkcja fn() i wyzwalacz dla bardzo podstawowej replikacji logicznej. Takie podejście jest tak prymitywne, że nie zadziała z kluczami obcymi, ale kod jest krótki:
db=# create or replace function tf() returns trigger as $$
begin
if TG_0P = 'INSERT' then
insert into r10 select NEW.*;
elseif TG_0P = 'UPDATE' then
delete from rl0 where pk = NEW.pk;
insert into rl0 select NEW.*;
elseif TG_0P = 'DELETE' then
delete from rl0 where pk = OLD.pk;
end if;
return case when TG_0P in ('INSERT','UPDATE') then NEW else OLD end;
end;
SS language plpgsql;
CREATE FUNCTION
Time: 8.531 ms
db=# create trigger t before insert or update or delete on r for each row execute procedure tf(); CREATE TRIGGER
Time: 8.813 ms
Przykład:
db=# insert into r(t) select chr(g) from generate_series(70,75) g;
INSERT 0 6
Time: 12.621 ms
db=# update r set t = 'updated' where pk=2;
UPDATE 1
Time: 10.398 ms
db=# delete from r where pk=1;
DELETE 1
Time: 9.634 ms
db=# select * from r;
pk | t
----+---------
3 | H
4 | I
5 | J
6 | K
2 | updated
(5 rows)
Time: 9.026 ms
db=# select * from rl0;
pk | t
----+---------
3 | H
4 | I
5 | J
6 | K
2 | updated
(5 rows)
Time: 1.201 ms
Na koniec sprawdź, czy replikujemy się do innej bazy danych:
db=# select *,current_setting('port') from dblink('upgrade.to.lO','select setting from pg_settings where name=$$port$$') as t(setting_10 text);
setting_10 | currerrt.setting
------------+------------------
5433 | 5432
(l row)
Time: 23.633 ms
Nazwałbym tę metodę najbardziej egzotyczną. Zarówno ze względu na fakt, że w przypadku replikacji strumieniowej, a później z pglogiką, użycie replikacji opartej na wyzwalaczu staje się mniej popularne. Ma większe obciążenie mastera, większą złożoność podczas konfiguracji i brak dobrze zorganizowanej dokumentacji. Nie ma tutaj przygotowania (jako takiego) procesu, ponieważ chcesz po prostu skonfigurować Slony na różnych głównych wersjach.
Zalety korzystania z tej metody obejmują…
- Nie trzeba wykonywać kopii zapasowych i przestojów (zwłaszcza, że stoisz za jakimś pgbouncerem lub haproxy).
Wady korzystania z tej metody obejmują…
- Wysoka złożoność konfiguracji
- Brak ustrukturyzowanej dokumentacji
- Niezbyt popularne – mniej przypadków użytkowników do zbadania (i udostępnienia)
W ten sam sposób, samodzielna replikacja wyzwalacza jest kolejnym możliwym sposobem uaktualnienia. Chociaż idea jest taka sama (rozkręcasz świeżą bazę danych o wyższej wersji i ustawiasz wyzwalacze w niższej wersji, aby wysłać do niej zmodyfikowane dane), napisana przez Ciebie konfiguracja będzie dla Ciebie jasna. Nie będziesz potrzebował wsparcia, a tym samym potencjalnie zużywasz mniej zasobów podczas jego uruchamiania. Oczywiście z tego samego powodu prawdopodobnie brakuje niektórych funkcji lub nie będą one działać zgodnie z oczekiwaniami. Jeśli masz kilka tabel do przejścia do nowych wersji, taka opcja prawdopodobnie zajmie Ci mniej czasu, a jeśli zostanie wykonana dobrze, może wymagać mniej zasobów. Jako bonus możesz połączyć niektóre transformacje ETL z aktualizacją, przełączając się na nową wersję bez przestojów.
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 dokumentReplikacja logiczna z pglogiką
To bardzo obiecujący nowy sposób na ulepszenie Postgresa. Chodzi o to, aby skonfigurować replikację logiczną między różnymi głównymi wersjami i dosłownie mieć równoległą bazę danych o wyższej (lub niższej) wersji obsługującej te same dane. Kiedy będziesz gotowy, po prostu przełącz połączenia ze swoją aplikacją ze starego na nowe.
Zalety korzystania z tej metody obejmują…
- W zasadzie brak przestojów
- Niezwykle obiecująca funkcja, znacznie mniej wysiłku niż replikacja oparta na wyzwalaczu
Wady korzystania z tej metody obejmują…
- Wciąż bardzo skomplikowana konfiguracja (szczególnie w przypadku starszych wersji)
- Brak ustrukturyzowanej dokumentacji
- Niezbyt popularne – mniej przypadków użytkowników do zbadania (i udostępnienia)
Migracje wersji głównej opartej na wyzwalaczu i replikacji pglogicznej można wykorzystać do obniżenia wersji (oczywiście do pewnej rozsądnej wartości, np. pglogical jest dostępny tylko w wersji 9.4, a replikacja wyzwalacza staje się coraz trudniejsza do skonfigurowania jako żądanej wersji przejść na starszą wersję).
Działania, które należy podjąć przed aktualizacją
- Zrób kopię zapasową
- Upewnij się, że na dysku jest wystarczająco dużo miejsca
- Sprawdź swoje rozszerzenia (ważne, że wszelkie zewnętrzne moduły są również kompatybilne z plikami binarnymi, chociaż nie można tego sprawdzić przez pg_upgrade)
- Upewnij się, że używasz tego samego datcollate i datctype itd. (sprawdź pg_database) w nowej bazie danych
- Sprawdź (DDL + Drop) widoki, funkcje, rozszerzenia, typy, które mogą zepsuć aktualizację
- Użyj --sprawdź, zanim naprawdę pg_upgrade
Działania, które należy podjąć po aktualizacji
- Skonsultuj się z pg_upgrade_server.log (jeśli używałeś pg_upgrade)
- Uruchom analizę na zaktualizowanych bazach danych (opcjonalnie, jak zrobiłoby to autovacuum, ale możesz wybrać, które relacje powinny być najpierw przeanalizowane, jeśli zrobisz to sam)
- Podgrzewaj popularne strony (opcjonalnie, ale może zwiększyć wydajność na początku)
Wniosek
Oto kilka ogólnych uwag, które warto wiedzieć, zanim zdecydujesz się na przejście do PostgreSQL w wersji 10…
- wprowadzono sekwencje pg_sequence, zmieniając zachowanie popularnego wcześniej SELECT * FROM nazwa_sekwencji - teraz tylko ostatnia_wartość | log_cnt | zwracane są is_ wywołane, ukrywając przed tobą "właściwości początkowe" (dostosuj dowolny kod, który opiera się na zmienionym zachowaniu)
- pg_basebackup domyślnie przesyła strumieniowo WAL. Po aktualizacji może być konieczne zmodyfikowanie skryptów (opcja -x usunięta)
- Wszystkie akcje pg_ctl czekają na zakończenie. Wcześniej trzeba było dodać -w, aby uniknąć próby połączenia się z bazą danych bezpośrednio po uruchomieniu pg_ctl. Tak więc, jeśli nadal chcesz używać "async" start lub stop, musisz wyraźnie zaznaczyć to za pomocą -W. Może być konieczne dostosowanie skryptów, aby działały zgodnie z przeznaczeniem.
- Wszystkie skrypty do archiwizacji WAL-ów lub monitorowania/kontrolowania replikacji strumieniowej lub PITR muszą zostać przejrzane, aby dostosować je do zmienionych nazw xlog. Np. select * from pg_is_xlog_replay_paused() nie będzie już pokazywać stanu powtórek podrzędnych WAL - musisz zamiast tego użyć select * from pg_is_wal_replay_paused(). Również cp /blah/pg_xlog/* należy zmienić na /blah/pg_wal/* i tak dalej w zasadzie dla wszystkich wystąpień pg_xlog. Powodem tak ogromnej, niezgodnej z poprzednimi wersjami zmiany jest rozwiązanie przypadku, gdy nowy użytkownik usuwa logi zapisu z wyprzedzeniem, aby „oczyścić trochę miejsca” poprzez usunięcie dzienników, i traci bazę danych.
- Dostosuj skrypty za pomocą pg_stat_replication dla nowych nazw (lokalizacja zmieniona na lsn)
- Dostosuj zapytania z ustawionymi funkcjami zwracania, jeśli to konieczne
- Jeśli używałeś pglogical jako rozszerzenia przed wersją 10, może być konieczne dostosowanie pg_hba.conf zmieniającej wartość między „kolumnami”
- Dostosuj skrypty do nowej nazwy pg_log, która jest dziennikiem, więc coś takiego jak find /pg_data/pg_log/postgresql-* -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .cii {} \; pracowałbym. Oczywiście możesz zamiast tego utworzyć dowiązanie symboliczne, ale należałoby podjąć działania, aby znaleźć logi w domyślnej lokalizacji. Kolejną małą zmianą w ustawieniach domyślnych jest log_line_prefix - jeśli twoje wyrażenie regularne zależało od określonego formatu, musisz je dostosować.
- Jeśli nadal używałeś niezaszyfrowanych haseł w swoich bazach danych Postgres, ta wersja została całkowicie usunięta. Czas więc uporządkować sprawy dla tych, którzy polegali na --niezaszyfrowanym...
- Reszta niekompatybilnych zmian z poprzednimi wydaniami jest albo zbyt świeża, aby można było się do nich odwoływać w dużej ilości kodu (min_parallel_relation_size), albo zbyt stara (zewnętrzne tsearch2) lub zbyt egzotyczna (usunięcie obsługi zmiennoprzecinkowych znaczników czasu w kompilacji), więc pominiemy je. Oczywiście są one wymienione na stronie wydania.
- Podobnie jak w przypadku 9.5 do 9.6, może być konieczne dostosowanie skryptów do odpytywania pg_stat_activity (jedna nowa kolumna i nowe możliwe wartości)
- Jeśli zapisywałeś/analizowałeś szczegółowe dane wyjściowe próżni, może być konieczne dostosowanie kodu
- Możesz również przyjrzeć się nowej implementacji partycjonowania — możesz chcieć zmienić swój istniejący „zestaw” w celu zapewnienia zgodności z nowymi „standardami”
- sprawdź oś czasu (zostanie zresetowana dla nowej bazy danych, jeśli zaktualizujesz pg_upgrade)
Oprócz tych kroków, które musisz wiedzieć, aby uaktualnić do wersji 10, jest wiele rzeczy, które sprawiają, że ta wersja jest bardzo wyczekiwana. Przeczytaj sekcję dotyczącą zmian w informacjach o wydaniu lub na blogu depesz.