Tuning baz Postgres – optymalizacja bufora zapisu

Tuning baz PostgreSQL - optymalizacja bufora zapisu

Czyli jak się pozbyć „brudnych stron”

Wykonując tuning baz Postgres, nie możemy zapominać o jednoczesnym tuningu systemu operacyjnego i systemu plików, na którym został zainstalowany. W przypadku niektórych jego parametrów konfiguracyjnych np. huge pages czy ustawień bgwritera takie działanie jest wręcz niezbędne. W tym artykule postaram się przybliżyć dwa parametry – vm.dirty_background_ratio oraz vm.dirty_ratio – będące podstawą tuningu systemu operacyjnego. Szczególnie w sytuacjach, gdy już wcześniej doświadczyliśmy problemów z niestabilnym działaniem bazy: wyraźnych skoków i spadków TPS-ów czy też znacznych opóźnień operacji zapisu.

vm.dirty_background_ratio – definiuje dopuszczalną wielkość bufora zapisu jako procent całkowitej pamięci systemowej, która może zostać wypełniona brudnymi stronami – tzn. takimi, które zostały w jakiś sposób zmodyfikowane i muszą zostać zapisane na dysku, zanim demon pdflush zacznie zapisywać je na dysk. Wartość domyślna tego parametru wynosi 10(%).

vm.dirty_ratio – domyślnie 20. Maksymalna wielkość bufora zapisu. Po jego osiągnięciu zapisy przechodzą w tryb synchroniczny, blokując wszelkie inne operacje zapisu, co przy dużym buforze zapisu i/lub małym buforze kontrolera może oznaczać katastrofę. Należy pamiętać, że wymuszenie zapisu jest niezbędne do zabezpieczenia danych, których nie można uznać za prawidłowo zabezpieczone, dopóki nie znajdą się na trwałym nośniku.

Optymalizacja bufora zapisu, czyli jak się pozbyć brudnych stron

W przypadku serwera z całkowitą ilością pamięci 6TB dopiero po przekroczeniu 600GB system zaczyna zrzucać je na dysk. Jeśli nie dysponujemy sprawną macierzą, a baza wciąż otrzymuje żądania zapisu, ryzykujemy osiągnięciem 1,2TB, czyli domyślnego progu dirty_ratio. Będzie to oznaczało całkowite zatrzymanie zapisów na serwerze i intensywny zapis brudnych stron przez demona pdflush aż do zmniejszenia rozmiaru bufora zapisu poniżej wartości wyznaczonej przez parametr dirty_ratio.

Jeśli z jakichś powodów nie chcemy używać proporcji względem całkowitej ilości pamięci, równie dobrze możemy zadeklarować wielkość bufora zapisu w bajtach za pomocą parametrów vm.dirty_background_bytes i vm.dirty_bytes.

Opisane wartości powinny być dostosowane na każdym serwerze bazodanowym bez względu na jego producenta. Nie ma, jak to zwykle bywa, wartości uniwersalnych. Ich ustawienie zależy zarówno od parametrów serwera, jak i specyfiki systemu. Oczywiście istnieją wskazówki – na przykład Red Hat zaleca następujące ustawienia dla baz danych:

vm.dirty_ratio = 15,
vm.dirty_background_ratio = 3.

Greg Smith, w swojej książce „Wysoko wydajny PostgreSQL 9.0/9.6”, sugeruje nawet obniżenie tych wartości do odpowiednio 2 i 1 dla systemów dysponujących dużą ilością pamięci.

Oczywiście najlepszymi wartościami dla konkretnego serwera będą takie, które zostały sprawdzone i przetestowane bezpośrednio na nim. Dlatego dobrą praktyką jest stopniowe obniżanie wartości domyślnych o wybraną wartość (np. 1%) i monitorowanie zachowania systemu po zmianie. Szczególnie należy zwrócić uwagę na zmiany w latencji zapytań, które znajdziemy np. na samym dole głównej strony raportu pgBadger.

Warto również monitorować /etc/meminfo, sprawdzając:

grep -A1 Dirty /proc/meminfo
Dirty:               128 kB
Writeback:             0 kB

Pierwsza wartość informuje nas o tym, ile brudnych stron znajduje się aktualnie w buforze, a druga – ile system usiłuje zapisać. Wysoka wartość Writeback powinna wzbudzić nasze zainteresowanie.

Tags

top