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

PostgreSQL:sześć nie tak łatwych elementów

PostgreSQL zawiera doskonały zestaw funkcji, niezrównany w przestrzeni RDBMS o otwartym kodzie źródłowym. Jest w większości łatwy do nauczenia i obsługi, szczególnie dla twórców aplikacji. Jednak niektóre części są po prostu niełatwe. Wymagają pracy w celu skonfigurowania i prawidłowego wykonania, a także mają kluczowe znaczenie dla działalności firmy.

Zarządzanie połączeniami

PostgreSQL uruchamia nowy proces, zwany procesem backendu , do obsługi każdego połączenia. Jest to przeciwieństwo nowoczesnych architektur obsługi połączeń opartych na pętli zdarzeń/puli wątków, które można znaleźć w innym porównywalnym oprogramowaniu serwerowym. Rozpoczęcie pełnego procesu zajmuje więcej czasu i zasobów oraz objawia się zwiększonymi opóźnieniami zapytań w aplikacjach, w których połączenia są otwierane i zamykane z dużą szybkością.

W większości wdrożeń na pewnym poziomie wymagana jest pula połączeń. Na poziomie aplikacji może to być użycie języka programowania/funkcji biblioteki. Na przykład sql/DB.SetMaxIdleConnsmożna użyć do zwiększenia ponownego wykorzystania połączenia z poziomu pojedynczej aplikacji Go.

Często jednak będziesz musiał użyć rozwiązania do puli połączeń lub równoważenia obciążenia innej firmy. Pule połączeń utrzymują pulę bezczynnych połączeń z nadrzędnym serwerem Postgres, które są przypisywane i udostępniane przychodzącym połączeniom klienckim. Zwykle analizują kod SQL wysyłany przez klientów w celu rozpoznania granic transakcji i modyfikujących dane DML w celu wdrożenia funkcji, takich jak tworzenie puli połączeń na poziomie transakcji i repliki do odczytu.

PgBouncer jest popularnym, lekkim programem do puli połączeń pojedynczych binarnych i często jest uruchamiany razem z PostgreSQL w tym samym systemie.

PgPool jest bardziej wszechstronny niż PgBouncer. Może również wykonywać na przykład równoważenie obciążenia i replikację.

Zestawianie połączeń wiąże się jednak z własnymi problemami. Po pierwsze, jest to dodatkowa część ruchoma, która została utrzymana w Twoim wdrożeniu. Konfiguracja uwierzytelniania jest również kłopotliwa, jeśli masz klientów korzystających z różnych poświadczeń lub mechanizmów uwierzytelniania. Niektóre funkcje na poziomie połączenia, takie jak LISTEN/NOTIFY, przygotowane instrukcje, tabele tymczasowe i tym podobne, mogą wymagać dodatkowej konfiguracji lub zmian po stronie klienta.

Bez aktualizacji przestojów

Aktualizacja PostgreSQL pomiędzy mniejszymi wersjami (13.x -> 13.y) obejmuje instalację nowego pakietu i ponowne uruchomienie procesu serwera. Podczas gdy ponowne uruchomienie procesu serwera z konieczności zakłóci działanie wszystkich podłączonych klientów, jest to nadal rozsądne pytanie, biorąc pod uwagę, że przestój jest związany z czasem trwania ponownego uruchomienia usługi.

Aktualizacja między głównymi wersjami (12.x -> 13.y) to jednak znacznie większa sprawa. Zazwyczaj im więcej jest danych, tym bardziej bolesny jest proces.

Najprostszą metodą, która działa tylko w przypadku niewielkich ilości danych (powiedzmy dziesiątki GB), jest zrzucenie danych ze starej wersji i przywrócenie ich na serwerze nowej wersji. Inną opcją jest użycie pg_upgrade, który wymaga skoordynowanego tańca obejmujących binaria obu wersji Postgresa.

W obu przypadkach bazy danych byłyby niedostępne przez dłuższy czas.

W idealnym przypadku powinna istnieć możliwość replikacji na nowy serwer wersji i promowania nowego serwera wersji jako podstawowego. Nie jest jednak możliwe wykonanie replikacji strumieniowej na serwer rezerwowy z inną wersją główną. Replikacja logiczna, chociaż wygląda dobrze do tego zadania, ma pewne problemy, które należy obejść, aby zapewnić pełną replikację.

Większość rozwiązań HA dla Postgres opiera się na replikacji strumieniowej, dlatego nie można uaktualniać węzłów w klastrze pojedynczo.

Obecny stan techniki polegałby na użyciu replikacji logicznej, przy jednoczesnym obejściu ograniczeń replikacji logicznej i prawdopodobnie obejmującym funkcje ograniczające, z których mogą korzystać aplikacje (takie jak DDL) podczas fazy uaktualniania.

Wysoka dostępność

PostgreSQL zawiera wszystkie funkcje niskiego poziomu wymagane do zbudowania rozwiązania HA:replikacja ze sprzężeniem zwrotnym, replikacja kaskadowa, replikacja synchroniczna, stany gotowości, gorące rezerwy, promocja stanu gotowości i tak dalej. W rzeczywistości nie zapewnia rozwiązania HA po wyjęciu z pudełka. Nie ma ram ani narzędzi do monitorowania kondycji i automatycznego przełączania awaryjnego do trybu gotowości. Nie ma pojęcia o wielowęzłowym klastrze HA.

Będziesz musiał skonfigurować i uruchomić rozwiązanie innej firmy do tworzenia wdrożeń Postgres o wysokiej dostępności. Aktualne ulubione to arepg_auto_failoverand Patroni. Chociaż Patroni opiera się na istniejącym, wysoce dostępnym magazynie konfiguracji, takim jak ZooKeeper lub etcd, pg_auto_failover może obejść się bez niego.

Ocena, wdrożenie i przetestowanie jednego z nich w środowisku produkcyjnym wymaga czasu i wysiłku. Należy skonfigurować i utrzymywać podręczniki monitorowania, alertów i operacji.

Zarządzanie rozdęciem

Architektura MVCC PostgreSQL oznacza, że ​​żadne dane nigdy nie są nadpisywane – modyfikacja wiersza powoduje tylko zapisanie nowej wersji wiersza na dysk. Usunięcie wiersza oznacza jedynie zapisanie, że wiersz jest niewidoczny dla przyszłych transakcji. Gdy wersja wiersza jest niedostępna z żadnych trwających lub przyszłych transakcji, nie jest już przydatna i jest określana jako „rozdęcie”. Proces zbierania śmieci nazywa się „próżnią”.

Rozdęcie jest niewidoczne dla aplikacji i staje się wyłącznie bólem głowy administratorów baz danych. W przypadku tabel z dużą ilością aktualizacji monitorowanie i zarządzanie rozdęciem to nietrywialny problem. tablelevel, aby zapewnić, że rozmiary stołów nie będą niekontrolowane.

Na indeksy wpływa również wzdęcie, a autovacuum tu nie pomaga. Usuwanie wierszy i aktualizacja indeksowanych kolumn prowadzą do martwych wpisów w indeksach. Duże obciążenia związane z aktualizacjami indeksowanych kolumn mogą prowadzić do stale rosnących i nieefektywnych indeksów. Nie ma odpowiednika próżni dla indeksów. Jedynym rozwiązaniem jest odbudowanie całego indeksu za pomocą REINDEX lub użycie VACUUM FULL na stole.

Poza pojedynczą wartością na tabelę (pg_stat_all_tables.n_dead_tup), Postgres nie oferuje niczego w sposobie szacowania rozrostu w tabeli i zupełnie nic dla indeksów. Najbardziej praktycznym sposobem nadal pozostaje wykonanie przerażająco wyglądającego zapytania z check_postgres.

pgmetrics zawiera zapytanie z check_postgres i może generować dane wyjściowe w formacie JSON i CSV, które zawierają informacje o rozmiarze i rozdęciu dla wszystkich tabel i indeksów; które można wprowadzić do narzędzi do monitorowania lub automatyzacji.

pg_repack to popularna alternatywa dla VACUUM FULL – może wykonać tę samą pracę, ale bez blokad. Jeśli jesteś zmuszony do regularnego ODkurzania PEŁNEGO, jest to niezbędne narzędzie.

zheap to nowy silnik pamięci masowej dla Postgres, rozwijany od lat, który obiecuje zmniejszyć rozrost dzięki aktualizacjom na miejscu.

Zarządzanie planem zapytań

Core PostgreSQL oferuje tylko dwa podstawowe narzędzia w tej przestrzeni:

  • pg_stat_statements rozszerzenie do analizy zapytań – daje łączne i średnie czasy planowania i wykonywania zapytań, wykorzystanie dysku i pamięci
  • automatyczne wyjaśnienie rozszerzenie, które może drukować plany wykonania zapytań do miejsca docelowego dziennika Postgres

Chociaż statystyki dostarczone przez pg_stat_statements są wystarczające, aby przejść, używając auto_explain aby wymusić plany w plikach dziennika, a następnie wyodrębnić je tak naprawdę nie więcej niż włamanie, zwłaszcza w porównaniu z komercyjnymi konkurentami Postgres, którzy oferują historię planów, tworzenie linii bazowych i funkcje zarządzania.

Obecny stan techniki w Postgres polega na wyszukiwaniu planów zapytań w pliku dziennika i przechowywaniu ich w innym miejscu. Ale być może największym problemem jest niemożność powiązania planu zapytania z odpowiednią analizą z pg_stat_statements. Sposób, w jaki pgDash to robi, polega na przeanalizowaniu zarówno tekstów zapytań SQL z danych wyjściowych pg_stat_statements i auto_explain, dostosowaniu do zniekształceń wykonanych przez pg_stat_statements i próbie dopasowania obu. Wymaga pełnego parsera języka PostgreSQL w dialekcie SQL.

Tworzenie linii bazowych, ustalanie zasad wyboru planu itp. po prostu nie jest obecnie możliwe w rdzeniu PostgreSQL.

Istnieje kilka rozszerzeń, które są zasadniczo ulepszonymi wersjami pg_stat_statements, ale dodatkowe kroki związane z korzystaniem z rozszerzenia strony trzeciej sprawiają, że jest to wyzwanie dla większości ludzi, zwłaszcza jeśli korzystają z zarządzanego dostawcy Postgres.

Dostrajanie

PostgreSQL ma mnóstwo opcji dostrajania, zaczynając od ustawienia under-configured-by-defaultshared_buffers. Niektóre są łatwe do zrozumienia i ustawienia, na przykład liczba równoległych procesów roboczych dla różnych operacji (max_worker_processes, max_parallel_* itp.). Inne obszary są nieco niejasne (wal_compression, random_page_cost itp.), ale ogólnie korzystne. Jednak najbardziej irytujące są te, które wymagają wymiernych informacji o obciążeniu pracą.

Na przykład, jeśli work_mem jest zbyt niski, zapytania mogą używać tymczasowych plików dyskowych; jeśli jest zbyt wysoki i jest wystarczająco dużo jednoczesnych zapytań, backendprocesy Postgresa mogą zostać zabite przez OOM. Jak więc dowiedzieć się, jaką liczbę ustawić?

W praktyce, zwłaszcza w przypadku obciążeń OLTP i aplikacji internetowych, nie można przewidzieć, jakie będzie szczytowe zapotrzebowanie na pamięć dla zapytań. Najlepszym rozwiązaniem jest ustawienie rozsądnej wartości, a następnie monitorowanie zapytań, aby zobaczyć, czy któreś z nich mogło skorzystać na wyższej wartości work_mem.

A jak to robisz? Musisz pobrać rozszerzenie auto_explain aby zarejestrować plany wykonania zapytań dla każdego zapytania, wyodrębnij je z plików dziennika Postgresa, zbadaj każdy plan zapytania, aby zobaczyć, czy używa zewnętrznych połączeń na dysku lub skanowania sterty bitmapy ze stratnymi blokami sterty.

Nie niemożliwe, po prostu trudne.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL:domyślne nazwy ograniczeń

  2. Polecenie Postgresql COPY dające błąd odmowy uprawnień

  3. Nowe dane nie są zachowywane w kolumnie tablicy Rails w Postgresie

  4. Czy można podać parametry dla nazwy tabeli lub kolumny w przygotowanych instrukcjach lub w QueryRunner.update()?

  5. Czy mogę wycofać już zatwierdzoną transakcję? (utrata danych)