Rozmiar początkowej bazy danych PostgreSQL

12

Moje pytanie składa się z 2 części.

  1. Czy istnieje sposób określenia początkowego rozmiaru bazy danych w PostgreSQL?
  2. Jeśli nie, to jak radzić sobie z fragmentacją, gdy baza danych rośnie z czasem?

Niedawno przeprowadziłem migrację z MSSQL do Postgres, a jedną z rzeczy, które zrobiliśmy w świecie MSSQL podczas tworzenia bazy danych, było określenie początkowego rozmiaru bazy danych i dziennika transakcji. Zmniejszyło to fragmentację i zwiększyło wydajność, zwłaszcza jeśli wcześniej znany był „normalny” rozmiar bazy danych.

Wydajność mojej bazy danych spada wraz ze wzrostem rozmiaru. Na przykład obciążenie, na które się narażam, zwykle zajmuje 10 minut. Wraz ze wzrostem bazy danych czas ten rośnie. Wydaje się, że wykonywanie VACUUM, VACUUM FULL i VACUUM FULL ANALYZE nie rozwiązuje problemu. Rozwiązaniem problemu z wydajnością jest zatrzymanie bazy danych, rozpakowanie dysku, a następnie wykonanie VACUUM FULL ANALYZE przywraca wydajność mojego testu z powrotem do pierwotnych 10 minut. To prowadzi mnie do podejrzeń, że fragmentacja powoduje ból.

Nie udało mi się znaleźć żadnego odniesienia do rezerwowania przestrzeni tabel / bazy danych w Postgres. Albo używam niewłaściwej terminologii i tym samym nie znajduję niczego, albo istnieje inny sposób ograniczania fragmentacji systemu plików w Postgres.

Jakieś wskazówki?

Rozwiązanie

Dostarczone odpowiedzi pomogły potwierdzić to, co zacząłem podejrzewać. PostgreSQL przechowuje bazę danych w wielu plikach, co pozwala jej rozwijać się bez obaw o fragmentację. Domyślne zachowanie polega na spakowaniu tych plików po brzegi danymi tabeli, co jest dobre w przypadku tabel, które rzadko się zmieniają, ale jest złe w przypadku tabel, które są często aktualizowane.

PostgreSQL wykorzystuje MVCC do zapewnienia równoczesnego dostępu do danych tabeli. W ramach tego schematu każda aktualizacja tworzy nową wersję wiersza, który został zaktualizowany (może to być sygnatura czasowa lub numer wersji, kto wie?). Stare dane nie są natychmiast usuwane, ale są oznaczane do usunięcia. Faktyczne usunięcie ma miejsce, gdy wykonywana jest operacja VACUUM.

Jak to się ma do współczynnika wypełnienia? Domyślny współczynnik wypełnienia tabeli wynoszący 100 w pełni pakuje strony tabeli, co z kolei oznacza, że ​​na stronie tabeli nie ma miejsca na zaktualizowane wiersze, tj. Zaktualizowane wiersze zostaną umieszczone na innej stronie tabeli niż oryginalny wiersz. Jest to niekorzystne dla wydajności, jak pokazuje moje doświadczenie. Ponieważ moje tabele podsumowań są bardzo często aktualizowane (do 1500 wierszy / s), zdecydowałem się ustawić współczynnik wypełnienia na 20, tj. 20% tabeli będzie dotyczyło wstawionych danych wierszy, a 80% danych aktualizacji. Choć może się to wydawać nadmierne, duża ilość miejsca zarezerwowanego dla zaktualizowanych wierszy oznacza, że ​​zaktualizowane wiersze pozostają na tej samej stronie, co oryginał, a strona tabeli nie jest pełna do czasu uruchomienia demona autovacuum w celu usunięcia przestarzałych wierszy.

Aby „naprawić” moją bazę danych, wykonałem następujące czynności.

  1. Ustaw współczynnik wypełnienia moich tabel podsumowań na 20. Możesz to zrobić w czasie tworzenia, przekazując parametr do CREATE TABLE lub po fakcie za pomocą ALTER TABLE. Wydałem następującą komendę plpgsql:ALTER TABLE "my_summary_table" SET (fillfactor = 20);
  2. Wydano VACUUM FULL, ponieważ zapisuje on całkowicie nową wersję pliku tabeli, a zatem domniemany zapisuje nowy plik tabeli z nowym współczynnikiem wypełnienia .

Po ponownym uruchomieniu testów nie widzę obniżenia wydajności, nawet jeśli baza danych jest tak duża, jak potrzebuję, i zawiera wiele milionów wierszy.

TL; DR - fragmentacja plików nie była przyczyną, była to fragmentacja obszaru tabel. Można to złagodzić, modyfikując współczynnik wypełnienia tabeli, aby dopasować go do konkretnego przypadku użycia.

CadentOrange
źródło
Wątpię, czy to operacja zmiany rozmiaru pliku. Domyślam się, że utrzymanie indeksów spowalnia wstawianie. Trwa dyskusja na tej liście dyskusyjnej PG (choć bez rozwiązania): postgresql.1045698.n5.nabble.com/…
a_horse_w_na_na_nie

Odpowiedzi:

4
  1. Nie jedyną rzeczą blisko tego jest kompilowanie serwera za pomocą przełącznika --with-segsize, może to pomóc, jeśli twój stół zajmuje więcej miejsca niż koncert, a twój system plików może obsłużyć pojedynczy plik będący gigantem. Jeśli wstawisz 20 koncertów, będziesz musiał utworzyć 20 plików, jeśli nie użyjesz tego przełącznika. Jeśli twój system plików może obsłużyć plik podczas koncertu, możesz po prostu ustawić na dużą wartość, najprawdopodobniej zobaczysz jakąś korzyść, w najgorszym przypadku małą korzyść.

  2. Spójrz na CLUSTER http://www.postgresql.org/docs/9.1/static/sql-cluster.html i FILLFACTOR http://www.postgresql.org/docs/9.1/static/sql-createtable.html , http://www.postgresql.org/docs/9.1/static/sql-createindex.html

Pamiętaj, że FILLFACTOR można zastosować zarówno do tabel, jak i indeksów.

Kuberchaun
źródło
5

W grze jest jeszcze jedna rzecz, która jeszcze nie weszła w twoje równania: GORĄCA aktualizacja . Powiązane odpowiedzi:

Ustawianie FILLFACTORtak bardzo, jak 20 nie wydają się nadmierne. Nadyma stół nawet pięciokrotnie. Jeśli aktualizacje HOT działają, nie powinieneś zejść tak nisko - normalnie .

Istnieją wyjątki: GORĄCE aktualizacje mogą ponownie wykorzystywać martwe krotki z poprzednich transakcji , a nie z tych samych lub jednoczesnych . Dlatego duże jednoczesne obciążenie lub długie transakcje, które wielokrotnie aktualizują te same wiersze, mogą gwarantować tak niskie (lub nawet niższe) ustawienie.

Jeśli masz duże aktualizacje, zmieniając jednocześnie duże części tabeli, możesz podzielić je na kilka części, najlepiej zmieniając tylko tyle wierszy na raz, ile zmieści się lokalnie na stronie danych. Ale trudno to oszacować i uregulować.

Pamiętaj, że aktualizacje HOT działają tylko wtedy, gdy zmienione kolumny nie są w żaden sposób zaangażowane w indeksy (ani jako dane, ani jako warunek w indeksie częściowym). Być może blokujesz GORĄCE aktualizacje za pomocą indeksów zaktualizowanych kolumn. Jeśli są one zbywalne, możesz uzyskać lepszą ogólną wydajność bez nich.

Na koniec możesz ustawić parametry automatycznej próżni dla każdej tabeli . Możesz kierować na mocno zaktualizowane tabele z agresywnymi ustawieniami, umożliwiającymi nieco ściślejsze upakowanie wierszy niż tylko FILLFACTOR 20.

Erwin Brandstetter
źródło
1
Interesujące rzeczy, przeczytam o tym i spróbuję lepiej zrozumieć, co oznaczają GORĄCE aktualizacje dla mojego systemu.
CadentOrange
4

Jeśli twoim problemem jest fragmentacja plików, to nie, nie ma. W Postgres każda tabela otrzymuje własny plik lub zestaw plików, jeśli używa TOAST, w systemie plików. Różni się to od, powiedzmy, Oracle (lub najwyraźniej MS-SQL), w którym tworzysz pliki przestrzeni tabel o dużych rozmiarach, aby upuścić do nich tabele - chociaż nawet tam możesz mieć problemy z fragmentacją systemu plików, jeśli pliki przestrzeni tabel zostaną rozszerzone lub system plików jest początkowo mocno rozdrobnione.

Co do twojego drugiego pytania ... nie mam pojęcia, jak w czysty sposób poradzić sobie z fragmentacją systemu plików, ponieważ MS-Windows to jedyny system operacyjny, w którym wystąpiły problemy z fragmentacją i nie uruchamiam MS-Windows bardziej niż absolutnie muszą być te dni. Być może umieszczenie plików bazy danych na ich własnych dyskach może to w pewnym stopniu złagodzić.

gsiems
źródło
Pamiętaj, że masz fragmentację wewnętrznej bazy danych PostgreSQL i fragmentację zewnętrznego systemu plików. Uważam, że wewnętrzne można złagodzić za pomocą VACUUM i za pomocą klastrów i wypełniacza. System plików może być obsługiwany przez uruchomienie defragmentacji dla danego systemu plików. Systemy plików Linux / Unix mogą się czasem fragmentować w zależności od obciążenia pracą i rodzaju systemu plików.
Kuberchaun
Fragmentacja systemu plików nie jest obecnie tak dużym problemem w NTFS.
a_horse_w_no_name
1
Myślałem, że NTFS był z tego znany? Moja stacja robocza dość dobrze się psuje, jedyne, co utrzymuje ją pod kontrolą, to zaplanowana defragmentacja, którą Windows7 uruchamia codziennie.
Kuberchaun,