Blog JSystems - uwalniamy wiedzę!

Szukaj

pg_upgrade, w skrócie

Aktualizacja klastra do nowej wersji:

pg_upgrade \
  -b /stara/bin -B /nowa/bin \
  -d /stara/data -D /nowa/data \
  --check
Z tego artykułu dowiesz się:
  • w jaki sposób zainstalować binaria wyższej wersji,
  • jak weryfikować czy wersje PostgreSQL są kompatybilne i czy upgrade zadziała (zanim spróbujemy i np. napsujemy),
  • jak wykonać upgrade ze zmianą istniejących plików danych,
  • jak wykonać upgrade z wykorzystaniem nowych plików danych,
  • jak sobie radzić z rozszerzeniami przy upgrade.

Aktualizować wersję PostgreSQL możemy na dwa sposoby. Możemy migrować w ramach jednej wersji np. 15.0-->15.1 lub pomiędzy wersjami np. 15-->16. W pierwszym wypadku wystarczy zainstalować nowe binarki i zrestartować serwer. W drugim wymagane jest trochę więcej pracy. Właśnie ten drugi przypadek przedstawię na przykładzie aktualizacji z wersji 15 do wersji 16.

Aktualizacja sprowadzać się będzie do stworzenia nowej PGDATA w której zostaną umieszczone pliki klastra po upgrade i samego upgrade kopiującego pliki do nowej PGDATA. Będziemy musieli tą nową PGDATA zainicjalizować, ale pg_upgrade nadpisze pliki danych i pliki konfiguracyjne z PGDATA źródłowego klastra.

Pamiętaj by przed aktualizacją wykonać kopię zapasową oryginalnego klastra!

Tworzę przykładową tabelę której istnienie będę weryfikował po upgrade klastra:

psql -c "create table abc(x integer)"

Mamy postawioną instancję klastra w wersji 15. Chcemy ją zaktualizować do wersji 16, zatem będą nam potrzebne binarki od tej wersji (jako użytkownik z prawami do sudo):

sudo apt-get -y install postgresql-16

Na potrzeby PGDATA klastra w wersji 16 tworzę odpowiedni katalog, zmieniam mu właściciela i inicjalizuję (jako użytkownik z prawami do sudo):

sudo mkdir /data_pg_new
sudo chown postgres:postgres /data_pg_new/
sudo chmod 700 /data_pg_new/
sudo su postgres
/usr/lib/postgresql/16/bin/initdb -D /data_pg_new

Zwróć uwagę na to, by inicjalizować klaster z użyciem binarki z tej nowszej, docelowej wersji PostgreSQL.

Muszę teraz położyć klaster w wersji 15 przed procesem upgrade (jako użytkownik systemowy postgres):

/usr/lib/postgresql/15/bin/pg_ctl -D /data_pg stop

Mogę teraz przejść do zasadniczej części, czyli aktualizacji klastra w wersji 15 do wersji 16. Podczas aktualizacji tworzony będzie plik "pg_upgrade_internal.log" w katalogu w którym się znajdujesz, musisz więc przejść do katalogu do którego użytkownik postgres ma uprawnienia, choćby do /tmp:

cd /tmp

Zaczniemy od sprawdzenia czy te dwie wersje klastrów są ze sobą kompatybilne, czy nie będzie żadnych problemów podczas aktualizacji. W tym celu wywołujemy (jako użytkownik systemowy postgres):

/usr/lib/postgresql/16/bin/pg_upgrade --old-bindir /usr/lib/postgresql/15/bin --new-bindir /usr/lib/postgresql/16/bin --old-datadir /data_pg --new-datadir /data_pg_new --check

Kluczowy jest tutaj przełącznik "--check" który powoduje jedynie sprawdzenie kompatybilności. Bez tego przełącznika dokonalibyśmy od razu aktualizacji, a nie o to nam przecież chodzi. Co prawda znaczenia przełączników można się domyślić po ich nazwie, jednak omówię każdy z nich. "--old-bindir" służy do wskazania gdzie leżą binarki starej wersji. "--new-bindir" służy do wskazania gdzie leżą binarki nowej wersji. "--old-datadir" wskazuje PGDATA starej wersji klastra. "--new-datadir" wskazuje PGDATA nowej wersji klastra.

Po wykonaniu tego polecenia powinniśmy zobaczyć mniej więcej coś takiego (lub informacje o braku kompatybilności - hope no):

Upgrade klastra PostgreSQL: ilustracja poglądowa

Nasze wersje są kompatybilne, w związku z czym możemy zaktualizować klaster. Faktyczna aktualizacja będzie różniła się jedynie brakiem przełącznika "--check". Możemy tu jeszcze ewentualnie użyć przełącznika "--link". Jeśli go nie użyjesz, oryginalny klaster pozostanie nienaruszony. Dane zostaną skopiowane do nowego klastra. To z jednej strony pozwoli nam zachować oryginalne pliki w przypadku jakiegoś fakapu, z drugiej strony potrzebujemy drugie tyle miejsca na dane ile jest w oryginalnym klastrze. Upgrade w związku z kopiowaniem danych może też trwać dosyć długo. - Użycie przełącznika "--link" spowoduje że zamiast kopiowania danych stworzenie linków symbolicznych do starych plików danych. Upgrade zajmie mniej czasu, nie potrzebujemy drugie tyle miejsca ale proces ten jest nieodwracalny.

Skoro weryfikacja kompatybilności przebiegła pomyślnie, możemy teraz przejść do faktycznego upgrade'u (wyciąłem tylko -check):

/usr/lib/postgresql/16/bin/pg_upgrade --old-bindir /usr/lib/postgresql/15/bin --new-bindir /usr/lib/postgresql/16/bin --old-datadir /data_pg --new-datadir /data_pg_new

Po uruchomieniu tej komendy zobaczymy wynik sprawdzania kompatybilności (taki jak przy samym sprawdzaniu) i informacje o kolejnych etapach aktualizacji:

Upgrade klastra PostgreSQL: ilustracja poglądowa (2)

Czas na uruchomienie naszego nowego klastra:

/usr/lib/postgresql/16/bin/pg_ctl -D /data_pg_new/ start

Możemy teraz zalogować się do nowego klastra i sprawdzić czy tabelka została przeniesiona, oraz w jakiej wersji jest klaster:

Upgrade klastra PostgreSQL: ilustracja poglądowa (3)

Przy upgrade klastra problem mogą stanowić rozszerzenia stworzone przez “CREATE EXTENSION”. Pojawia się tu problem kompatybilności wersji rozszerzeń. Najprostszym wyjściem jest skasować rozszerzenie przed upgradem, wykonanie upgrade klastra i następnie ponowne stworzenie rozszerzeń już w nowej wersji. Można też wybrać wersję trudniejszą bez kasowania rozszerzeń. Weźmy za przykład PostgreSQL w wersji 12 i PostGiS w wersji 3.0. Chcemy zrobić upgrade PostgreSQL do wersji 16 i PostGiS do wersji 3.5. W takim przypadku trzeba zrobić upgrade dwa razy. Wynika to z tego, że PostgreSQL w wersji 12 nie wspiera PostGiSa w wersji 3.5, a PostgreSQL w wersji 16 nie wspiera PostGiSa w wersji 3.5. Trzeba najpierw zrobić upgrade PostgreSQL do wersji która wspiera obie wersje PostGiSa - w tym przypadku do wersji 14. Następnie zrobić upgrade PostGiSa do wersji 3.5 i dopiero wtedy zaktualizować PostgreSQL do wersji 16 z PostGiSem już w wersji 3.5.

Pamiętaj że po upgrade w klastrze docelowym będziemy mieli pliki konfiguracyjne (postgresql.conf, postgresql.auto.conf, pg_hba.conf) przywrócone do domyślnego stanu. Czyli wszystkie Twoje ustawienia na poziomie klastra zostają wyzerowane. Jeśli chcesz zachować ustawienia, musisz przenieść je na nowy klaster:

/usr/lib/postgresql/16/bin/pg_ctl -D /data_pg_new/ stop
cp /data_pg/postgresql.conf /data_pg_new/
cp /data_pg/postgresql.auto.conf /data_pg_new/
cp /data_pg/pg_hba.conf /data_pg_new/
/usr/lib/postgresql/16/bin/pg_ctl -D /data_pg_new/ start
Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane

Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →

To szkolenie może być dofinansowane dla Ciebie z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Kiedy potrzebny jest pg_upgrade, a kiedy wystarczy sama wymiana binariów?
Przy migracji w obrębie jednej wersji, na przykład 15.0 do 15.1, wystarczy zainstalować nowe binaria i zrestartować serwer. Przy zmianie wersji głównej, na przykład 15 do 16, potrzebne jest więcej pracy i właśnie tam używa się pg_upgrade.
Po co używać przełącznika --check przed właściwym upgrade?
Przełącznik --check powoduje jedynie sprawdzenie kompatybilności obu wersji klastra, bez faktycznej aktualizacji. Pozwala wykryć problemy, zanim spróbujesz upgrade i coś zepsujesz. Sama aktualizacja różni się od sprawdzenia tylko brakiem tego przełącznika.
Czym różni się upgrade z przełącznikiem --link od domyślnego?
Bez --link dane są kopiowane, oryginalny klaster pozostaje nienaruszony, ale potrzeba drugie tyle miejsca i proces trwa dłużej. Z --link zamiast kopiowania tworzone są linki symboliczne, więc upgrade jest szybszy i oszczędniejszy, ale nieodwracalny.
Co dzieje się z plikami konfiguracyjnymi po upgrade?
Pliki postgresql.conf, postgresql.auto.conf i pg_hba.conf w klastrze docelowym wracają do stanu domyślnego, więc wszystkie ustawienia klastra są wyzerowane. Aby je zachować, trzeba skopiować te pliki ze starego klastra do nowego i zrestartować serwer.
Jak wykonać upgrade, gdy w bazie są rozszerzenia?
Najprościej usunąć rozszerzenie przed upgrade, wykonać aktualizację klastra i stworzyć rozszerzenie ponownie w nowej wersji. Przy niekompatybilnych wersjach rozszerzeń, jak PostGIS, czasem trzeba wykonać upgrade dwustopniowo, przez wersję wspierającą oba warianty.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...