Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
PostgreSQL
deadlock detected - jak zdiagnozować i uniknąć zakleszczeń
Deadlock to nie to samo co zwykła blokada. Przy zwykłej blokadzie jedna sesja czeka, aż druga skończy. Przy zakleszczeniu obie czekają na siebie i nigdy by się nie doczekały - dlatego PostgreSQL sam przerywa jedną z nich. Pokazujemy, jak odczytać przyczynę z logu i jak zaprojektować kod, żeby deadlocki zniknęły.
W logu aplikacji i serwera pojawia się ERROR: deadlock detected wraz z DETAIL, który opisuje, który proces czekał na który. Błąd ma kod SQLSTATE 40P01. Charakterystyczne jest to, że występuje nieregularnie, tylko przy zbieżności konkretnych operacji, i często pod obciążeniem. Jedna transakcja dostaje błąd i jest wycofywana, druga zwykle kończy się poprawnie.
Zakleszczenie powstaje, gdy transakcje pobierają blokady w niespójnej kolejności. Klasyczny przykład: transakcja A aktualizuje wiersz 1, potem chce wiersz 2. Transakcja B w tym samym czasie zaktualizowała wiersz 2, a teraz chce wiersz 1. A czeka na B, B czeka na A - cykl.
PostgreSQL nie zapobiega temu z góry, bo byłoby to kosztowne. Zamiast tego okresowo (co deadlock_timeout, domyślnie 1 sekunda) uruchamia detektor zakleszczeń. Gdy wykryje cykl, wybiera jedną z transakcji jako ofiarę i ją wycofuje, przerywając cykl. Ofiara dostaje błąd 40P01 i to jej zadaniem jest powtórzyć operację. Deadlocki są zawsze skutkiem wzorca dostępu w kodzie, a nie usterki bazy - dlatego rozwiązanie leży po stronie aplikacji.
ALTER SYSTEM SET log_lock_waits = on; i upewnij się, że log_min_messages obejmuje poziom ERROR. Wykonaj SELECT pg_reload_conf();.SELECT ... FOR UPDATE w ustalonej kolejności, zamiast pozwalać, by blokady powstawały przypadkowo w trakcie. Dla operacji na całej tabeli można użyć LOCK TABLE ... IN SHARE ROW EXCLUSIVE MODE.Po ujednoliceniu kolejności dostępu obserwuj log serwera - komunikaty deadlock detected powinny przestać się pojawiać lub ich częstość drastycznie spaść. Możesz zliczyć wystąpienia w logu za ostatnią dobę, żeby porównać przed i po zmianie. Jeśli masz środowisko testowe, odtwórz scenariusz, który wcześniej wywoływał zakleszczenie (dwie równoległe transakcje w odwrotnej kolejności) i potwierdź, że teraz jedna czeka na drugą i obie kończą się poprawnie, zamiast wpaść w cykl.
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...