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

Dostrajanie operacji wejścia/wyjścia (I/O) dla PostgreSQL

PostgreSQL jest jedną z najpopularniejszych baz danych typu open source na świecie i ma udane wdrożenia w kilku środowiskach o znaczeniu krytycznym w różnych domenach, wykorzystując wysokiej klasy aplikacje OLTP działające w czasie rzeczywistym, wykonujące miliony i miliardy transakcji dziennie. PostgreSQL I/O jest dość niezawodny, stabilny i wydajny na prawie każdym sprzęcie, w tym nawet w chmurze.

Aby zapewnić, że bazy danych działają w oczekiwanej skali z oczekiwanymi czasami odpowiedzi, istnieje potrzeba inżynierii wydajności. Cóż, osiągnięcie dobrej wydajności bazy danych zależy od wielu czynników. Wydajność bazy danych może ulec pogorszeniu z różnych powodów, takich jak wymiarowanie infrastruktury, nieefektywna strategia konserwacji bazy danych, słaby kod SQL lub źle skonfigurowane procesy bazy danych, które nie wykorzystują wszystkich dostępnych zasobów - procesora, pamięci, przepustowości sieci i we/wy dysku.

Co może spowodować spadek wydajności bazy danych?

  • Źle napisane zapytania ze złymi łączeniami, logiką itp., które zajmują dużo procesora i pamięci
  • Kwerendy wykonujące pełne skanowanie dużych tabel z powodu nieprawidłowego indeksowania
  • Zła konserwacja bazy danych bez odpowiednich statystyk
  • Nieefektywne planowanie pojemności skutkujące niedostatecznie zwymiarowaną infrastrukturą
  • Niewłaściwy projekt logiczny i fizyczny
  • Brak puli połączeń, co powoduje, że aplikacje nawiązują ogromną liczbę połączeń w niekontrolowany sposób

Jest to więc wiele potencjalnych obszarów, które mogą powodować problemy z wydajnością. Jednym z istotnych obszarów, na których chciałbym się skupić w tym blogu, jest dostrajanie wydajności We/Wy PostgreSQL (wejście/wyjście). Dostrajanie operacji wejścia / wyjścia PostgreSQL jest niezbędne, szczególnie w środowisku o dużej liczbie transakcji, takim jak OLTP lub w środowisku hurtowni danych ze złożoną analizą danych na dużych zestawach danych.

W większości przypadków problemy z wydajnością bazy danych są spowodowane głównie dużą liczbą operacji we/wy. Oznacza to, że procesy bazy danych spędzają więcej czasu na zapisie lub odczytaniu z dysku. Każda operacja na danych w czasie rzeczywistym jest powiązana we/wy, konieczne jest zapewnienie dostrojenia bazy danych we/wy. W tym blogu skupię się na typowych problemach I/O, które bazy danych PostgreSQL mogą napotkać w środowiskach produkcyjnych czasu rzeczywistego.

Dostrajanie we/wy PostgreSQL

Strojenie We/Wy PostgreSQL jest niezbędne do zbudowania wysoce wydajnej i skalowalnej architektury bazy danych. Przyjrzyjmy się różnym czynnikom wpływającym na wydajność we/wy:

  • Indeksowanie
  • Partycjonowanie
  • Punkty kontrolne
  • ODKURZA, ANALIZA (z WYPEŁNIANIEM)
  • Inne problemy we/wy
  • We/Wy PostgreSQL w chmurze
  • Narzędzia

Indeksowanie

Indeksowanie jest jedną z podstawowych technik strojenia, która odgrywa kluczową rolę w poprawie wydajności operacji we/wy bazy danych. Dotyczy to naprawdę każdej bazy danych. PostgreSQL obsługuje różne typy indeksów, które mogą znacznie przyspieszyć operacje odczytu, zapewniając zwiększoną skalowalność aplikacji. Chociaż tworzenie indeksów jest dość proste i nieskomplikowane, administratorzy baz danych i programiści muszą mieć wiedzę o tym, jaki typ indeksu wybrać i w jakich kolumnach. Ta ostatnia opiera się na różnych czynnikach, takich jak złożoność zapytania, typ danych, kardynalność danych, ilość zapisów, rozmiar danych, architektura dysku, infrastruktura (chmura publiczna, chmura prywatna lub lokalna) itp.

Chociaż indeksowanie może znacznie poprawić wydajność odczytu zapytań, może również spowolnić zapisy trafiające do indeksowanych kolumn. Spójrzmy na przykład:

Wpływ indeksów na operacje READ

Tabela o nazwie emp z około 1 milionem wierszy.

PRZECZYTAJ wyniki bez indeksu

postgres=# select * from emp where eid=10;

 eid | ename    | peid | did  |    doj
-----+---------------+--------+------+------------
  10 | emp        |          |   1   | 2018-06-06
(1 row)
 
Time: 70.020 ms => took about 70+ milli-seconds to respond with on row

PRZECZYTAJ wyniki za pomocą indeksu

Umieśćmy indeks na kolumnie eid i zobaczmy różnicę

postgres=# create index indx001 on emp ( eid );
CREATE INDEX

postgres=# select * from emp where eid=10;

 eid | ename  | peid | did |    doj
------+-------------+-------+------+------------
  10 | emp      |          |   1   | 2018-06-06
(1 row)
 
Time: 0.454 ms =>  0.4+ milli-seconds!!! thats a huge difference - isn’t it?

Dlatego indeksowanie jest ważne.

Wpływ indeksów na operacje WRITE

Indeksy spowalniają wydajność zapisów. Chociaż indeksy mają wpływ na wszystkie rodzaje operacji zapisu, przyjrzyjmy się analizie wpływu indeksów na WSTAWKI

Wstawianie 1 miliona wierszy do tabeli bez indeksów

postgres=# do $$
postgres$# declare
postgres$# i integer;
postgres$# begin
postgres$# for i in 1..1000000 loop
postgres$# insert into emp values (i,'emp',null,1,current_date);
postgres$# end loop;
postgres$# end $$;
DO

Time: 4818.470 ms (00:04.818) => Takes about 4.8 seconds

Wstawianie tego samego miliona wierszy z indeksem

Najpierw utwórzmy indeks

postgres=# create index indx001 on emp ( eid );
CREATE INDEX

postgres=# do $$
postgres$# declare
postgres$# i integer;
postgres$# begin
postgres$# for i in 1..1000000 loop
postgres$# insert into emp values (i,'emp',null,1,current_date);
postgres$# end loop;
postgres$# end $$;
DO

Time: 7825.494 ms (00:07.825) =>  Takes about 7.8 seconds

Tak więc, jak możemy zaobserwować, czas INSERT wzrósł o 80% przy tylko jednym indeksie i może zająć znacznie więcej czasu, gdy istnieje wiele indeksów. Może być jeszcze gorzej, gdy istnieją indeksy oparte na funkcjach. Z tym muszą żyć DBA! Indeksy zwiększą wydajność zapisu. Istnieją jednak sposoby rozwiązania tego problemu, który zależy od architektury dysku. Jeśli serwer bazy danych korzysta z wielu dyskowych systemów plików, indeksy i tabele można umieścić w wielu obszarach tabel znajdujących się w wielu dyskowych systemach plików. W ten sposób można osiągnąć lepszą wydajność we/wy.

WSKAZÓWKI dotyczące zarządzania indeksami

  • Zrozum potrzebę indeksów. Kluczem jest inteligentne indeksowanie.
  • Unikaj tworzenia wielu indeksów i zdecydowanie żadnych zbędnych indeksów, może to naprawdę obniżyć wydajność zapisu.
  • Monitoruj użycie indeksów i usuwaj wszystkie nieużywane indeksy.
  • Gdy zindeksowane kolumny podlegają zmianom danych, indeksy również ulegają rozdęciu. Dlatego regularnie reorganizuj indeksy.

Partycjonowanie

Skuteczna strategia partycjonowania może w dużym stopniu zmniejszyć problemy z wydajnością we/wy. Duże tabele można podzielić na partycje na podstawie logiki biznesowej. PostgreSQL obsługuje partycjonowanie tabel. Chociaż obecnie nie obsługuje w pełni wszystkich funkcji, może pomóc tylko w niektórych przypadkach użycia w czasie rzeczywistym. W PostgreSQL podzielone na partycje tabele podrzędne są całkowicie niezależne od tabeli głównej, która stanowi wąskie gardło. Np. Ograniczenia utworzone w tabeli głównej nie mogą być automatycznie dziedziczone do tabel podrzędnych.

Jednak z perspektywy równoważenia we/wy partycjonowanie może naprawdę pomóc. Wszystkie partycje podrzędne można podzielić na wiele obszarów tabel i systemów plików dysku. Zapytania z zakresem dat w klauzuli „gdzie” trafiające do tabeli, podzielone na partycje na podstawie zakresu dat, mogą skorzystać na partycjonowaniu, po prostu skanując jedną lub dwie partycje zamiast pełnej tabeli.

Punkt kontrolny

Punkty kontrolne definiują spójny stan bazy danych. Są one krytyczne i ważne jest, aby punkty kontrolne występowały wystarczająco regularnie, aby zapewnić trwałe zapisanie zmian danych na dysku, a baza danych była przez cały czas w spójnym stanie. Biorąc to pod uwagę, niewłaściwa konfiguracja punktów kontrolnych może prowadzić do problemów z wydajnością we/wy. Administratorzy baz danych muszą skrupulatnie konfigurować punkty kontrolne, aby upewnić się, że nie ma skoków we/wy, a także zależy to od tego, jak dobre są dyski i jak dobrze zaprojektowano układ plików danych.

Co robi punkt kontrolny?

Mówiąc prościej, punkty kontrolne zapewnią:

  • Wszystkie zatwierdzone dane są zapisywane w plikach danych na dysku.
  • pliki zatykania są aktualizowane ze statusem zatwierdzenia.
  • Pliki dziennika transakcji w katalogu pg_xlog (obecnie pg_wal) są przetwarzane.

To wyjaśnia, jak intensywnie działają punkty kontrolne we/wy. W postgresql.conf znajdują się parametry, które można skonfigurować / dostroić, aby kontrolować zachowanie punktu kontrolnego, a tymi parametrami są max_wal_size, min_wal_size, checkpoint_timeout i checkpoint_completion_target. Te parametry decydują, jak często punkty kontrolne powinny się pojawiać i w jakim czasie punkty kontrolne muszą się zakończyć.

Jak zrozumieć, jaka konfiguracja jest lepsza dla punktów kontrolnych? Jak je dostroić?

Oto kilka wskazówek:

  • Oceń bazę danych TPS. Oceń całkowitą liczbę transakcji występujących w bazie danych w ciągu dnia roboczego, a także określ, o której godzinie do bazy danych trafia największa liczba transakcji.
  • Omawiaj regularnie z twórcami aplikacji i innymi zespołami technicznymi, aby zrozumieć statystyki szybkości transakcji bazy danych, a także przyszły wzrost transakcji.
  • Można to zrobić również na końcu bazy danych:
    • Monitoruj bazę danych i oceniaj liczbę transakcji występujących w ciągu dnia. Można to zrobić, wysyłając zapytania do tabel pgcatalog, takich jak pg_stat_user_tables.

    • Oceń liczbę plików archiwów wal generowanych dziennie

    • Monitoruj, aby zrozumieć, jak działają punkty kontrolne, włączając parametr log_checkpoints

      2018-06-06 15:03:16.446 IST [2111] LOG:  checkpoint starting: xlog
      2018-06-06 15:03:22.734 IST [2111] LOG:  checkpoint complete: wrote 12112 buffers (73.9%); 0 WAL file(s) added, 0 removed, 25 recycled; write=6.058 s, sync=0.218 s, total=6.287 s; sync files=4, longest=0.178 s, average=0.054 s; distance=409706 kB, estimate=412479 kB
    • Sprawdź, czy bieżąca konfiguracja punktu kontrolnego jest wystarczająco dobra dla bazy danych. Skonfiguruj parametr checkpoint_warning (domyślnie ustawiony na 30 sekund), aby zobaczyć poniższe ostrzeżenia w plikach dziennika postgres.

      2018-06-06 15:02:42.295 IST [2111] LOG:  checkpoints are occurring too frequently (11 seconds apart)
      2018-06-06 15:02:42.295 IST [2111] HINT:  Consider increasing the configuration parameter "max_wal_size".

Co oznacza powyższe ostrzeżenie?

Punkty kontrolne zwykle występują, gdy zapełniony jest max_wal_size (1 GB domyślnie, co oznacza 64 pliki WAL) lub gdy zostanie osiągnięty checkpoint_timeout (co 5 minut, co domyślnie). Powyższe ostrzeżenie oznacza, że ​​skonfigurowany max_wal_size nie jest odpowiedni, a punkty kontrolne pojawiają się co 11 sekund, co z kolei oznacza, że ​​64 pliki WAL w katalogu PG_WAL są zapełniane w ciągu zaledwie 11 sekund, co jest zbyt częste. Innymi słowy, jeśli transakcje są rzadsze, to punkty kontrolne będą pojawiać się co 5 minut. Tak więc, jak sugeruje podpowiedź, zwiększ parametr max_wal_size do wyższej wartości, parametr max_min_size można zwiększyć do tej samej lub mniejszej niż poprzednia.

Innym krytycznym parametrem do rozważenia z perspektywy wydajności we/wy jest checkpoint_completion_target, który jest domyślnie skonfigurowany na 0.5.

checkpoint_completion_target =0,5 x checkpoint_timeout =2,5 minuty

Oznacza to, że punkty kontrolne mają 2,5 minuty na zsynchronizowanie brudnych bloków z dyskiem. Czy wystarczy 2,5 minuty? Trzeba to ocenić. Jeśli liczba brudnych bloków do zapisania jest bardzo duża, 2,5 minuty może wydawać się bardzo agresywne i wtedy można zaobserwować skok we/wy. Skonfigurowanie parametru complete_target należy wykonać w oparciu o wartości max_wal_size i checkpoint_timeout. Jeśli te parametry zostaną podniesione do wyższej wartości, rozważ odpowiednie zwiększenie checkpoint_completion_target.

ODKURZA, ANALIZA (z FILLFACTOR)

VACUUM to jedna z najpotężniejszych funkcji PostgreSQL. Może być używany do usuwania nadwyżek (pofragmentowanych przestrzeni) w tabelach i indeksach i jest generowany przez transakcje. Baza danych musi być regularnie poddawana PRÓŻNIU, aby zapewnić zdrową konserwację i lepszą wydajność. Ponownie, nieregularne ODKURZACZ bazy danych może prowadzić do poważnych problemów z wydajnością. ANALIZA musi być wykonana razem z VACUUM (analiza próżniowa), aby zapewnić aktualne statystyki dla planera zapytań.

ANALIZA PRÓŻNIOWA może być wykonywana na dwa sposoby:ręczny, automatyczny lub oba. W środowisku produkcyjnym czasu rzeczywistego są to na ogół oba. Automatyczne ODKURZACZ jest włączane przez parametr „autovacuum”, który domyślnie jest ustawiony na „on”. Po włączeniu automatycznego odkurzania PostgreSQL automatycznie rozpoczyna okresowe odkurzanie tabel. Kandydackie stoły wymagające odkurzania są pobierane przez procesy automatycznego odkurzania w oparciu o różne progi ustawione przez różne parametry automatycznego odkurzania*, parametry te można modyfikować/dostrajać, aby zapewnić okresowe usuwanie wzdęć tabel. Przyjrzyjmy się niektórym parametrom i ich zastosowaniu -

Parametry automatycznego odkurzania

autovacuum=on Ten parametr służy do włączania/wyłączania automatycznego odkurzania. Domyślnie jest „włączone”.
log_autovacuum_min_duration =-1 Zapisuje czas trwania procesu automatycznego odkurzania. Jest to ważne, aby zrozumieć, jak długo trwał proces automatycznego odkurzania.
autovacuum_max_workers =3 Liczba potrzebnych procesów automatycznego odkurzania. Zależy to od tego, jak agresywne są transakcje w bazie danych i ile procesorów możesz zaoferować dla procesów automatycznego odkurzania.
autovacuum_naptime =1 min Czas spoczynku automatycznego odkurzania między cyklami automatycznego odkurzania.

Parametry definiujące próg rozpoczęcia procesu Autovacuum

Zadania autoodkurzania rozpoczynają się po osiągnięciu określonego progu. Poniżej znajdują się parametry, których można użyć do ustawienia określonego progu, na podstawie którego rozpocznie się proces automatycznego odkurzania.

autovacuum_vacuum_threshold =50 Tabela zostanie odkurzona, gdy co najmniej 50 wierszy zostanie zaktualizowanych/usuniętych w tabeli.
autovacuum_analyze_threshold =50 Tabela zostanie przeanalizowana, gdy minimum 50 wierszy zostanie zaktualizowanych/usuniętych w tabeli.
autovacuum_vacuum_scale_factor =0,2 Tabela zostanie odkurzona, gdy co najmniej 20% wierszy zostanie zaktualizowanych/usuniętych w tabeli.
autovacuum_analyze_scale_factor =0,1 Tabela zostanie odkurzona, gdy co najmniej 10% wierszy zostanie zaktualizowanych/usuniętych w tabeli.

Parametry powyżej progu można modyfikować na podstawie zachowania bazy danych. Administratorzy baz danych będą musieli przeanalizować i zidentyfikować gorące tabele oraz upewnić się, że te tabele są odkurzane tak często, jak to możliwe, aby zapewnić dobrą wydajność. Osiągnięcie określonej wartości tych parametrów może być wyzwaniem w środowisku o dużej liczbie transakcji, w którym zmiany danych następują co sekundę. Wiele razy zauważyłem, że procesy autoodkurzania trwają dość długo, co kończy się zużyciem zbyt wielu zasobów w systemach produkcyjnych.

Sugerowałbym, aby nie polegać całkowicie na procesie autoodkurzania, najlepszym sposobem jest zaplanowanie nocnej pracy ANALIZA PRÓŻNI, aby zmniejszyć obciążenie autoodkurzaniem. Na początek rozważ ręczne ODKURZANIE dużych stołów o wysokim współczynniku transakcji.

PRÓŻNIA PEŁNA

VACUUM FULL pomaga odzyskać nadętą przestrzeń w tabelach i indeksach. Tego narzędzia nie można używać, gdy baza danych jest w trybie online, ponieważ blokuje tabelę. Tabele muszą być poddawane PRÓŻNI PEŁNEJ tylko wtedy, gdy aplikacje są wyłączone. Indeksy zostaną również przeorganizowane wraz z tabelami podczas PRÓŻNI PEŁNEJ.

Przyjrzyjmy się wpływowi ANALIZY PRÓŻNI

Wzdęcia:Jak rozpoznać wzdęcia? Kiedy generowane są wzdęcia?

Oto kilka testów:

Mam tabelę o rozmiarze 1 GB z 10 milionami wierszy.

postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;

 ?column? 
----------------
        1

postgres=# select count(*) From pgbench_accounts ;
  count   
-----------------
 10000000

Przyjrzyjmy się wpływowi rozrostów na proste zapytanie:wybierz * z pgbench_accounts;

Poniżej znajduje się plan wyjaśnienia zapytania:

postgres=# explain analyze select * from pgbench_accounts;

QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
 Seq Scan on pgbench_accounts  (cost=0.00..263935.00 rows=10000000 width=97) 
 (actual time=0.033..1054.257 rows=10000000 loops=1)
 Planning time: 0.255 ms
 Execution time: 1494.448 ms

Teraz zaktualizujmy wszystkie wiersze w tabeli i zobaczmy wpływ powyższego zapytania SELECT.

postgres=# update pgbench_accounts set abalance=1;
UPDATE 10000000

postgres=# select count(*) From pgbench_accounts ;
  count   
-----------------
 10000000

Poniżej znajduje się PLAN WYJAŚNIENIA zapytania po wykonaniu UPDATE.

postgres=# explain analyze select * from pgbench_accounts;

QUERY PLAN                                                             
----------------------------------------------------------------------------------------------------------------------------------------------------------
 Seq Scan on pgbench_accounts  (cost=0.00..527868.39 rows=19999939 width=97) 
 (actual time=404.474..1520.175 rows=10000000 loops=1)
 Planning time: 0.051 ms
 Execution time: 1958.532 ms

Rozmiar tabeli wzrósł do 2 GB po aktualizacji

postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;

 ?column? 
-----------------
        2

Jeśli możesz zaobserwować i porównać liczby kosztów wcześniejszego PLANU WYJAŚNIENIA, istnieje ogromna różnica. Koszt wzrósł o dużą marżę. Co ważniejsze, jeśli przyjrzysz się uważnie, liczba wierszy (nieco ponad 19 milionów) skanowanych po aktualizacji jest wyższa, co stanowi prawie dwa razy więcej niż faktycznie istniejące wiersze (10 milionów). Oznacza to, że liczba nadętych wierszy wynosi ponad 9 milionów, a rzeczywisty czas również wzrósł, a czas wykonania wzrósł z 1,4 sekundy do 1,9 sekundy.

Taki jest więc wpływ nieodkurzania TABELI po UPDATE. Powyższe liczby EXPLAIN PLAN dokładnie oznaczają, że stół jest rozdęty.

Jak rozpoznać, czy stół jest nadęty? Użyj modułu pgstattuple contrib:

postgres=# select * from pgstattuple('pgbench_accounts');
 table_len  | tuple_count | tuple_len  | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent 
------------+-------------+------------+---------------+------------------+----------------+--------------------+------------+--------------
 2685902848 |    10000000 | 1210000000 |         45.05 |          9879891 |     1195466811 |              44.51 |   52096468 |         1.94

Powyższa liczba wskazuje, że połowa stołu jest nadęta.

Przeanalizujmy tabelę PRÓŻNIOWĄ i zobaczmy teraz wpływ:

postgres=# VACUUM ANALYZE pgbench_accounts ;
VACUUM

postgres=# explain analyze select * from pgbench_accounts;

QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------
 Seq Scan on pgbench_accounts  (cost=0.00..428189.05 rows=10032005 width=97) 
 (actual time=400.023..1472.118 rows=10000000 loops=1)
 Planning time: 4.374 ms
 Execution time: 1913.541 ms

Po ANALIZA PRÓŻNI liczby kosztów spadły. Teraz liczba zeskanowanych wierszy zbliża się do 10 milionów, również rzeczywisty czas i czas wykonania niewiele się zmieniły. Dzieje się tak dlatego, że chociaż rozrosty w tabeli zniknęły, rozmiar skanowanej tabeli pozostaje taki sam. Poniżej znajduje się wyjście pgstattuple po ANALIZA PRÓŻNI.

postgres=# select * from pgstattuple('pgbench_accounts');

 table_len  | tuple_count | tuple_len  | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent 
------------+-------------+------------+---------------+------------------+----------------+--------------------+------------+--------------
 2685902848 |    10000000 | 1210000000 |         45.05 |             0 |              0 |                  0 | 1316722516 |        49.02

Powyższa liczba wskazuje, że wszystkie wzdęcia (martwe krotki) zniknęły.

Przyjrzyjmy się wpływowi PEŁNEJ ANALIZY PODCIŚNIENIA i zobaczmy, co się stanie:

postgres=# vacuum full analyze pgbench_accounts ;
VACUUM

postgres=# explain analyze select * from pgbench_accounts;

                            QUERY PLAN                                                            
---------------------------------------------------------------------------
 Seq Scan on pgbench_accounts  (cost=0.00..263935.35 rows=10000035 width=97) 
(actual time=0.015..1089.726 rows=10000000 loops=1)
 Planning time: 0.148 ms
 Execution time: 1532.596 ms

Jeśli zaobserwujesz, rzeczywisty czas i liczby czasu wykonania są podobne do liczb przed UPDATE. Ponadto rozmiar tabeli zmniejszył się teraz z 2 GB do 1 GB.

postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;

 ?column? 
-----------------
        1

Taki jest wpływ VACUUM FULL.

FILLFACTOR

FILLFACTOR to bardzo ważny atrybut, który może naprawdę zmienić strategię utrzymania bazy danych na poziomie tabeli i indeksu. Ta wartość wskazuje ilość miejsca do wykorzystania przez wkładki INSERT w bloku danych. Wartość FILLFACTOR domyślnie wynosi 100%, co oznacza, że ​​WSTAWKI mogą wykorzystać całą dostępną przestrzeń w bloku danych. Oznacza to również, że nie ma miejsca na aktualizacje. Ta wartość może zostać zmniejszona do określonej wartości w przypadku mocno aktualizowanych tabel.

Ten parametr można skonfigurować dla każdej tabeli i indeksu. Jeśli FILLFACTOR jest skonfigurowany do optymalnej wartości, możesz zobaczyć prawdziwą różnicę w wydajności VACUUM i wydajności zapytań. Krótko mówiąc, optymalne wartości FILLFACTOR zapewniają, że niepotrzebna liczba bloków nie jest przydzielana.

Spójrzmy na ten sam przykład powyżej -

Tabela ma milion wierszy

postgres=# select count(*) From pgbench_accounts ;
  count   
-----------------
 10000000

Przed aktualizacją rozmiar tabeli wynosi 1 GB

postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;

?column? 
--------
   1

postgres=# update pgbench_accounts set abalance=1;
UPDATE 10000000

Po aktualizacji rozmiar tabeli wzrósł do 2 GB po AKTUALIZACJI

postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;

?column? 
---------
    2

Oznacza to, że liczba bloków przydzielonych do tabeli wzrosła o 100%. Jeśli skonfigurowano FILLFACTOR, rozmiar tabeli mógł nie zwiększyć się o ten margines.

Jak się dowiedzieć, jaką wartość skonfigurować w FILLFACTOR?

Wszystko zależy od tego, jakie kolumny są aktualizowane i od rozmiaru aktualizowanych kolumn. Ogólnie rzecz biorąc, dobrze byłoby ocenić wartość FILLFACTOR, testując ją w bazach danych UAT. Jeśli aktualizowane kolumny stanowią, powiedzmy, 10% całej tabeli, rozważ skonfigurowanie współczynnika wypełnienia na 90% lub 80%.

Ważna uwaga:
Jeśli zmienisz wartość FILLFACTOR dla istniejącej tabeli z danymi, będziesz musiał wykonać VACUUM FULL lub reorganizację tabeli, aby upewnić się, że wartość FILLFACTOR obowiązuje dla istniejących danych.

WSKAZÓWKI DOTYCZĄCE ODKURZANIA

  • Jak wspomniano powyżej, rozważ ręczne uruchamianie zadania ANALIZA PRÓŻNI każdej nocy na intensywnie używanych stołach, nawet gdy włączona jest funkcja automatycznego odkurzania.
  • Rozważ uruchomienie ANALIZY PODCIŚNIENIOWEJ na tabelach po zbiorczym WSTAWIENIU. Jest to ważne, ponieważ wielu uważa, że ​​VACUUMing może nie być potrzebne po WSTAWKACH.
  • Monitoruj, aby upewnić się, że wysoce aktywne tabele są regularnie odkurzane, wysyłając zapytania do tabeli pg_stat_user_tables.
  • Użyj modułu contrib pg_stattuple, aby określić rozmiar nadętej przestrzeni w segmentach tabeli.
  • Narzędzia VACUUM FULL nie można używać w produkcyjnych systemach baz danych. Rozważ użycie narzędzi takich jak pg_reorg lub pg_repack, które pomogą reorganizować tabele i indeksy online bez blokad.
  • Upewnij się, że proces AUTOVACUUM działa przez dłuższy czas w godzinach pracy (o dużym natężeniu ruchu).
  • Włącz parametr log_autovacuum_min_duration, aby rejestrować czasy i czas trwania procesów AUTOVACUUM.
  • Ważne, upewnij się, że FILLFACTOR jest skonfigurowany do optymalnej wartości dla wysokich tabel transakcji i indeksó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 dokument

Inne problemy we/wy

Sortowanie dysków

Zapytania wykonujące sortowanie są kolejnym powszechnym zjawiskiem w produkcyjnych bazach danych w czasie rzeczywistym i większości z nich nie da się uniknąć. Zapytania wykorzystujące klauzule takie jak GROUP BY, ORDER BY, DISTINCT, CREATE INDEX, VACUUM FULL itp. wykonują sortowanie, a sortowanie może odbywać się na dysku. Sortowanie odbywa się w pamięci, jeśli selekcja i sortowanie odbywa się na podstawie indeksowanych kolumn. Tutaj kluczową rolę odgrywają indeksy złożone. Indeksy są agresywnie buforowane w pamięci. W przeciwnym razie, jeśli pojawi się potrzeba posortowania danych na dysku, wydajność drastycznie spadnie.

Aby zapewnić sortowanie w pamięci, można użyć parametru work_mem. Ten parametr można skonfigurować na taką wartość, że całe sortowanie można wykonać w pamięci. Podstawową zaletą tego parametru jest to, że poza konfiguracją w postgresql.conf, można go również skonfigurować na poziomie sesji, użytkownika lub bazy danych. Jaka powinna być wartość work_mem? Jak się dowiedzieć, które zapytania wykonują sortowanie dysków? Jak monitorować zapytania wykonujące sortowanie dysków w produkcyjnej bazie danych w czasie rzeczywistym?

Odpowiedź brzmi - skonfiguruj parametr log_temp_files na określoną wartość. Wartość jest w bajtach, wartość 0 rejestruje wszystkie pliki tymczasowe (wraz z ich rozmiarami) wygenerowane na dysku w wyniku sortowania dysków. Po skonfigurowaniu parametru będziesz mógł zobaczyć następujące komunikaty w plikach dziennika

2018-06-07 22:48:02.358 IST [4219] LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp4219.0", size 200425472
2018-06-07 22:48:02.358 IST [4219] STATEMENT:  create index bid_idx on pgbench_accounts(bid);
2018-06-07 22:48:02.366 IST [4219] LOG:  duration: 6421.705 ms  statement: create index bid_idx on pgbench_accounts(bid);

Powyższy komunikat oznacza, że ​​zapytanie CREATE INDEX wykonało sortowanie dysków i wygenerowało plik o rozmiarze 200425472 bajtów, czyli 191+ MB. To dokładnie oznacza, że ​​parametr work_mem musi być skonfigurowany na 191+ MB lub więcej, aby to konkretne zapytanie wykonało sortowanie pamięci.

Cóż, dla zapytań aplikacji parametr work_mem można skonfigurować tylko na poziomie użytkownika. Zanim to zrobisz, uważaj na liczbę połączeń, które użytkownik wykonuje z bazą danych i liczbę zapytań sortujących wykonywanych przez tego użytkownika. Ponieważ PostgreSQL próbuje przydzielić work_mem do każdego procesu (wykonując sortowanie) w każdym połączeniu, co może potencjalnie zagłodzić pamięć na serwerze bazy danych.

Układ systemu plików bazy danych

Zaprojektowanie wydajnego i sprzyjającego wydajności układu systemu plików bazy danych jest ważne z punktu widzenia wydajności i skalowalności. Co ważne, nie jest to zależne od rozmiaru bazy danych. Ogólnie uważa się, że bazy danych o dużych rozmiarach będą wymagały architektury dysku o wysokiej wydajności, co NIE jest prawdą. Nawet jeśli rozmiar bazy danych wynosi 50 GB, możesz potrzebować dobrej architektury dysku. A to może nie być możliwe bez ponoszenia dodatkowych kosztów.

Oto kilka WSKAZÓWEK dotyczących tego samego:

  • Upewnij się, że baza danych ma wiele obszarów tabel, z tabelami i indeksami pogrupowanymi na podstawie stawek transakcji.
  • Przestrzeń tabel musi być umieszczona na wielu dyskowych systemach plików, aby zapewnić zrównoważone we/wy. Zapewni to również udział wielu procesorów w celu wykonywania transakcji na wielu dyskach.
  • Rozważ umieszczenie katalogu pg_xlog lub pg_wal na oddzielnym dysku w bazie danych o dużej liczbie transakcji.
  • Upewnij się, że parametry *_cost są skonfigurowane na podstawie infrastruktury
  • Użyj iostat, mpstat i innych narzędzi do monitorowania I/O, aby zrozumieć statystyki I/O na wszystkich dyskach i odpowiednio zaprojektuj/zarządzaj obiektami bazy danych.

PostgreSQL w chmurze

Infrastruktura ma kluczowe znaczenie dla dobrej wydajności bazy danych. Strategie inżynierii wydajności różnią się w zależności od infrastruktury i środowiska. Należy zwrócić szczególną uwagę na bazy danych PostgreSQL hostowane w chmurze. Testy wydajności dla baz danych hostowanych na fizycznych serwerach szkieletowych w lokalnym centrum danych mogą być zupełnie inne niż bazy danych hostowane w chmurze publicznej.

Ogólnie rzecz biorąc, instancje w chmurze mogą być nieco wolniejsze, a testy porównawcze różnią się znacznym marginesem, zwłaszcza pod względem I/O. Zawsze wykonuj sprawdzanie opóźnień we/wy przed wybraniem / zbudowaniem instancji w chmurze. Ku mojemu zdziwieniu dowiedziałem się, że wydajność instancji chmury może się różnić w zależności od regionu, nawet jeśli pochodzą one od tego samego dostawcy chmury. Aby to dokładniej wyjaśnić, instancja w chmurze z tymi samymi specyfikacjami zbudowana w dwóch różnych regionach może dać różne wyniki wydajności.

Zbiorcze ładowanie danych

Operacje zbiorczego ładowania danych offline są dość powszechne w świecie baz danych. Mogą generować znaczne obciążenie we/wy, co z kolei spowalnia wydajność ładowania danych. W swoim doświadczeniu jako DBA stawiałem czoła takim wyzwaniom. Często ładowanie danych staje się strasznie powolne i trzeba je dostroić. Oto kilka porad. Pamiętaj, że dotyczą one tylko operacji ładowania danych w trybie offline i nie mogą być brane pod uwagę przy wczytywaniu danych do działającej produkcyjnej bazy danych.

  • Ponieważ większość operacji ładowania danych jest wykonywana poza godzinami pracy, upewnij się, że podczas ładowania danych zostały skonfigurowane następujące parametry -
    • Skonfiguruj wystarczająco duże wartości związane z punktami kontrolnymi, aby punkty kontrolne nie powodowały żadnych problemów z wydajnością.
    • Wyłącz full_page_write
    • Wyłącz archiwizację ściany
    • Skonfiguruj parametr synchronous_commit na „wyłączony”
    • Upuść ograniczenia i indeksy dla tych tabel poddanych ładowaniu danych (ograniczenia i indeksy można odtworzyć po załadowaniu danych z większą wartością work_mem)
    • Jeśli ładujesz dane z pliku CSV, większy maintenance_work_mem może zapewnić dobre wyniki.
    • Chociaż przyniesie to znaczną poprawę wydajności, NIE wyłączaj parametru fsync, ponieważ może to prowadzić do uszkodzenia danych.

WSKAZÓWKI dotyczące analizy wydajności chmury

  • Przeprowadź dokładne testy opóźnień we/wy za pomocą pgbench. Z mojego doświadczenia wynika, że ​​podczas sprawdzania opóźnień dysku w ramach oceny TPS miałem całkiem zwyczajne wyniki wydajności. Wystąpiły problemy z wydajnością pamięci podręcznej w niektórych instancjach chmury publicznej. Pomoże to wybrać odpowiednie specyfikacje dla instancji chmury wybranej dla baz danych.
  • Instancje w chmurze mogą działać różnie w zależności od regionu. Instancja w chmurze z określonymi specyfikacjami w regionie może dawać inne wyniki wydajności w porównaniu z instancją w chmurze z takimi samymi specyfikacjami w innym regionie. Moje testy pgbench wykonane na wielu instancjach w chmurze (wszystkie te same specyfikacje z tym samym dostawcą chmury) w różnych regionach dały mi różne wyniki w niektórych z nich. Jest to ważne zwłaszcza podczas migracji do chmury.
  • Wydajność zapytań w chmurze może wymagać innego podejścia do dostrajania. Administratorzy baz danych będą musieli używać parametrów *_cost, aby zapewnić generowanie zdrowych planów wykonywania zapytań.

Narzędzia do monitorowania wydajności PostgreSQL

There are various tools to monitor PostgreSQL performance. Let me highlight some of those.

  • pg_top is a GREAT tool to monitor PostgreSQL database dynamically. I would highly recommend this tool for DBAs for various reasons. This tool has numerous advantages, let me list them out:
    • pg_top tool uses textual interface and is similar to Unix “top” utility.
    • Will clearly list out the processes and the hardware resources utilized. What excites me with this tool is that it will clearly tell you if a particular process is currently on DISK or CPU - in my view that’s excellent. DBAs can clearly pick the process running for longer time on the disk.
    • You can check the EXPLAIN PLAN of the top SQLs dynamically or instantly
    • You can also find out what Tables or Indexes are being scanned instantly
  • Nagios is a popular monitoring tool for PostgreSQL which has both open-source and commercial versions. Open source version should suffice for monitoring. Custom Perl scripts can be built and plugged into Nagios module.
  • Pgbadger is a popular tool which can be used to analyze PostgreSQL log files and generate performance reports. This report can be used to analyze the performance of checkpoints, disk sorting.
  • Zabbix is another popular tool used for PostgreSQL monitoring.

ClusterControl is an up-and-coming management platform for PostgreSQL. Apart from monitoring, it also has functionality to deploy replication setups with load balancers, automatic failover, backup management, among others.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wyświetlić listę wszystkich widoków w bazie danych PostgreSQL

  2. Seminarium internetowe :Nowe funkcje w PostgreSQL 11 [Kontynuacja]

  3. Czy UUID jako klucz podstawowy w PostgreSQL da złą wydajność indeksu?

  4. Jak make_timestamp() działa w PostgreSQL

  5. Odejmij minuty od wartości czasu w PostgreSQL