Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
PostgreSQL
Transakcja się nie kończy - zapomniany COMMIT/ROLLBACK
COMMIT lub ROLLBACK transakcja pozostaje otwarta w nieskończoność, blokując wiersze i zatrzymując usuwanie martwych krotek w całym klastrze.To cichy zabójca wydajności: aplikacja albo człowiek w narzędziu graficznym rozpoczyna transakcję poleceniem BEGIN, wykonuje jakieś zmiany i... nie robi COMMIT ani ROLLBACK. Transakcja zostaje otwarta, sesja przechodzi w stan "idle in transaction" i tak wisi - minutami, a czasem godzinami. Przez ten czas trzyma blokady na zmodyfikowanych wierszach i, co gorsza, blokuje sprzątanie martwych wersji wierszy w całej bazie. Objawy potrafią wyglądać jak poważna awaria, choć źródło jest banalne: jedna zapomniana transakcja.
Użytkownicy zgłaszają, że część operacji "wisi". Zaglądasz do aktywności bazy i widzisz sesję w stanie idle in transaction, której xact_start (czas rozpoczęcia transakcji) sprzed wielu minut lub godzin. Inne zapytania, które chcą zmodyfikować te same wiersze, czekają na zwolnienie blokad. Równolegle rośnie bloat i pojawia się dziwny objaw: autovacuum pracuje, ale liczba martwych wierszy w tabelach wcale nie spada. W skrajnym przypadku w logach zaczynają się ostrzeżenia o zbliżającym się przekroczeniu zakresu identyfikatorów transakcji. Często winowajcą jest klient graficzny z wyłączonym autocommit, w którym ktoś wykonał UPDATE, po czym poszedł na obiad, albo aplikacja, która pobrała połączenie z puli, otworzyła transakcję i nie zwolniła go po błędzie.
W PostgreSQL każda zmiana musi być domknięta: COMMIT ją utrwala, ROLLBACK wycofuje. Dopóki żadne z tych poleceń nie padnie, transakcja jest otwarta i aktywna z punktu widzenia silnika - nawet jeśli sesja nic nie robi (stąd stan "idle in transaction"). Otwarta transakcja ma dwa kosztowne skutki. Po pierwsze trzyma blokady założone przez swoje zmiany, więc inni czekają. Po drugie, i groźniej, ustala tak zwany horyzont: mechanizm wielowersyjności (MVCC) nie może usunąć wersji wierszy, które mogłyby być jeszcze widoczne dla najstarszej otwartej transakcji w klastrze. Dlatego jedna zapomniana transakcja blokuje sprzątanie martwych krotek nie tylko w swojej tabeli, ale w całej bazie - autovacuum mieli, lecz nie może niczego zwolnić. To także droga do problemu z zakresem identyfikatorów transakcji, jeśli taka sesja wisi bardzo długo. Przyczyną bywa wyłączony autocommit w kliencie, błąd w kodzie aplikacji, który nie domyka transakcji po wyjątku, albo połączenie oddane do puli bez wcześniejszego ROLLBACK.
SELECT pid, usename, state, xact_start, now() - xact_start AS czas_transakcji, query FROM pg_stat_activity WHERE state = 'idle in transaction' ORDER BY xact_start;. Kolumna query pokaże ostatnie polecenie, a czas_transakcji - jak długo to trwa.COMMIT; lub - gdy zmian nie chcesz zachować - ROLLBACK;. To najczystsze rozwiązanie.SELECT pg_terminate_backend(); , podstawiając PID z pierwszego kroku. PostgreSQL wykona wtedy automatyczny rollback tej transakcji.ALTER SYSTEM SET idle_in_transaction_session_timeout = '5min'; i przeładuj konfigurację przez SELECT pg_reload_conf();. Od tej pory serwer sam zamknie każdą transakcję bezczynną dłużej niż ustawiony limit.ROLLBACK przed oddaniem połączenia do puli.Powtórz zapytanie z pierwszego kroku - lista sesji w stanie idle in transaction z długim czasem trwania powinna być pusta. Że blokady zniknęły, potwierdzisz przez SELECT count(*) FROM pg_locks WHERE NOT granted; - brak nieprzyznanych blokad oznacza, że nikt już nie czeka. Skuteczność sprzątania martwych wierszy sprawdzisz po chwili w pg_stat_user_tables: po zamknięciu długiej transakcji autovacuum wreszcie zdoła obniżyć n_dead_tup. Że limit czasu bezczynności faktycznie obowiązuje, potwierdzi SHOW idle_in_transaction_session_timeout; z ustawioną wartością - a najlepszym dowodem będzie to, że kolejna celowo pozostawiona otwarta transakcja zostanie samodzielnie zamknięta przez serwer po upływie tego czasu, z odpowiednim wpisem w logu.
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...