Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
PostgreSQL
Jak podejrzeć aktywne zapytania i blokady w pg_stat_activity
pg_stat_activity, a łańcuch blokad rozwikłujemy funkcją pg_blocking_pids oraz widokiem pg_locks.Widok pg_stat_activity to pierwsze miejsce, do którego zaglądamy, gdy baza "muli" albo coś wisi. Pokażemy Ci, jak z niego czytać stan sesji i jak w kilka sekund znaleźć zapytanie, które blokuje resztę.
Użytkownicy zgłaszają, że zapis do jednej tabeli "się zawiesza", choć serwer nie jest przeciążony. W logu widać rosnący czas oczekiwania na blokady, a pojedyncze UPDATE lub ALTER TABLE nie wracają. Nie wiesz jednak, która sesja trzyma blokadę i jak długo. Czasem winowajcą jest długo otwarta transakcja (idle in transaction), czasem ciężki raport, a czasem migracja schematu, która czeka na blokadę na poziomie tabeli. Zanim cokolwiek zabijesz, musisz zobaczyć pełny obraz: kto jest aktywny, kto czeka, i na kogo.
PostgreSQL steruje współbieżnym dostępem za pomocą blokad. Większość z nich jest zdejmowana od razu i nie widać ich gołym okiem, ale gdy dwie transakcje chcą tego samego zasobu w niekompatybilnych trybach, jedna musi poczekać. Widok pg_stat_activity pokazuje po jednym wierszu na proces serwera i mówi, w jakim jest stanie (active, idle, idle in transaction), na co czeka (wait_event_type i wait_event), od kiedy (state_change, query_start, xact_start) oraz jakie zapytanie wykonuje. Kluczowe jest zrozumienie, że blokada sama w sobie nie jest awarią - awarią jest dopiero blokada trzymana zbyt długo przez transakcję, która powinna była się już zakończyć.
SELECT pid, usename, state, wait_event_type, wait_event, now() - query_start AS trwa, left(query, 60) AS zapytanie FROM pg_stat_activity WHERE state <> 'idle' ORDER BY query_start;idle in transaction - to najczęstsza przyczyna blokad trzymanych bez powodu. Sprawdź ich xact_start, żeby ocenić, jak długo transakcja jest otwarta.SELECT pid, pg_blocking_pids(pid) AS blokuja, wait_event, left(query,60) FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid)) > 0;. Kolumna blokuja to lista PID-ów trzymających blokadę.pg_locks z pg_stat_activity: SELECT l.pid, l.locktype, l.mode, l.granted, a.state FROM pg_locks l JOIN pg_stat_activity a USING (pid) WHERE NOT l.granted; - wiersze z granted = false to sesje, które czekają.pg_cancel_backend(pid); jeśli wisi w otwartej transakcji, zakończ sesję przez pg_terminate_backend(pid).idle_in_transaction_session_timeout, rozważ lock_timeout dla migracji i statement_timeout dla ról aplikacyjnych.Po interwencji uruchom ponownie zapytanie z pg_blocking_pids - dla wcześniej czekających sesji lista blokujących powinna być już pusta, a wcześniej zablokowane polecenie ruszy dalej. W pg_locks nie powinno być już Twoich wierszy z granted = false na spornym obiekcie. Warto też sprawdzić pg_stat_activity pod kątem tego, czy problematyczna sesja zmieniła stan (przy anulowaniu) albo zniknęła z listy (przy terminowaniu). Jeżeli blokady wracają cyklicznie, to znak, że przyczyna leży w kodzie aplikacji - szukaj miejsca, które otwiera transakcję i nie zamyka jej odpowiednio szybko.
Wróć do listy: 100 najczęstszych pytań i problemów z PostgreSQL

Sprawdź szkolenie: Administracja, replikacja i tuning baz danych PostgreSQL
To szkolenie może być dofinansowane z KFS lub BUR.
★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Sprawdź szkolenie: Zaawansowana administracja PostgreSQL (HA, DR, monitoring, skalowanie)
To szkolenie może być dofinansowane z KFS lub BUR.
★★★★★Średnia ocena naszych szkoleń w Google: 5/5
Komentarze (0)
Brak komentarzy...