PostgreSQL čaká na zámok. Ako nájsť blokujúcu transakciu?

Dotazy stoja, hoci server má voľnú kapacitu. Postup na nájdenie blokujúcej relácie, posúdenie zásahu a nastavenie limitov čakania.

Tyrkysový visiaci zámok na kovovom plote s farebným rozostreným pozadím
Fotografia: Paulius Dragunas / Unsplash

Uloženie objednávky čaká, požiadavky končia timeoutom a CPU databázy neukazuje preťaženie. Jednou z možností je transakcia, ktorá bráni ostatným získať potrebný zámok. Pred reštartom si vytvorte obraz o tom, kto čaká a kto mu stojí v ceste. Nasledujúci postup vychádza z PostgreSQL 18 a bežných transakčných zámkov; pripravené transakcie a advisory locks potrebujú osobitný rozbor.

Najprv potvrďte čakanie na zámok

Pre prvý prehľad použite čítací dotaz: SELECT pid, pg_blocking_pids(pid) AS blockers FROM pg_stat_activity WHERE wait_event_type = 'Lock'; Výsledok ukáže príslušné čakajúce PID a ich blokujúcich predchodcov. Ak je prázdny, nesnažte sa problém nasilu vysvetliť zámkami. Zaznamenajte čas merania a porovnajte ho s konkrétnou zlyhávajúcou požiadavkou.

Uložte si aj názov aplikácie a dotknutú databázu. Pri odovzdávaní diagnostiky obmedzte výpis na potrebné údaje; text dotazu môže obsahovať citlivé hodnoty. Vopred odlíšte pozorovanie od zásahu. Samotné získanie prehľadu nemá byť dôvodom na hromadné rušenie dotazov alebo odpájanie klientov.

Sledujte reťaz až k pôvodnému blokovaniu

pg_blocking_pids() môže vrátiť držiteľa konfliktného zámku aj čakajúcu reláciu, ktorá je v poradí pred vami. Preto pre nájdené PID preverujte aj ich vlastné blokovanie. Prvý predchodca nemusí byť začiatkom problému. Nevyberajte cieľ zásahu iba podľa najdlhšie čakajúcej používateľskej požiadavky; môže byť len ďalšou obeťou v reťazi.

Stav idle in transaction označuje otvorenú transakciu bez práve bežiaceho dotazu. Porovnajte xact_start, application_name a vlastníka relácie. Zobrazenie cudzích podrobností môže vyžadovať pg_read_all_stats. Zistite, či ide o plánovanú dávku, nasadenie alebo zabudnutú operáciu. Dĺžku transakcie posudzujte podľa jej účelu a dopadu, nie podľa univerzálnej hranice.

Zásah vyberte podľa stavu relácie

pg_cancel_backend(pid) ruší aktuálny dotaz, pg_terminate_backend(pid) ukončuje celú reláciu. Pri nečinnej otvorenej transakcii nie je čo rušiť ako bežiaci dotaz. S vlastníkom dohodnite ukončenie transakcie; ROLLBACK v jej pôvodnom spojení zahodí nepotvrdené zmeny. Nepoužívajte COMMIT len preto, aby sa ostatné požiadavky pohli, ak neviete, čo tým potvrdíte.

Pred prípadným ukončením relácie znovu overte jej identitu a dopad na rozpracovanú operáciu. Tieto funkcie vyžadujú príslušné oprávnenia. Hodnota true pri pg_terminate_backend(pid) bez timeoutu potvrdzuje odoslanie signálu, nie dokončené ukončenie. Po zásahu preto skontrolujte reláciu, reťaz blokovania aj výsledok v aplikácii. Jeden úspešný administrátorský príkaz incident neuzatvára.

Obmedzte čakanie a overte používateľský výsledok

lock_timeout obmedzuje každý pokus o získanie zámku; statement_timeout obmedzuje trvanie príkazu. Ak používate oba, kratší lock_timeout umožní osobitne zachytiť čakanie na zámok. SET LOCAL platí len v aktuálnej transakcii. Hodnoty zvoľte podľa operácie a vyskúšajte spolu s obsluhou chyby v aplikácii. Timeout je hranica čakania, nie oprava blokujúcej práce.

Zámky riadkov a tabuliek sa spravidla držia do konca transakcie. Skráťte preto úsek, počas ktorého ich operácia potrebuje; pri viacerých objektoch dodržujte rovnaké poradie prístupu. Zmenu overte súbežnými operáciami v oddelenom prostredí. V produkcii následne porovnajte čakanie a chybovosť a zopakujte pôvodne zlyhávajúce uloženie objednávky. Úspešné načítanie úvodnej stránky tento zápis nepreverí.

  • Zaznamenajte čakajúce PID, čas a dotknutú operáciu.
  • Prejdite reťaz predchodcov a určte vlastníka blokovania.
  • Rozlíšte zrušenie dotazu, rollback a ukončenie relácie.
  • Overte uvoľnenie čakania aj skutočný zápis v aplikácii.

Čo si odniesť

Pri blokovaní databázy hľadajte transakciu, ktorá drží ostatné operácie v čakaní. Najprv si uložte dôkazy, potom zvoľte cielený zásah s vlastníkom služby. Oprava je potvrdená až vtedy, keď pôvodná používateľská operácia opäť dokončí svoju prácu.

Dokumentácia a ďalšie čítanie

Mgr. Martin Hlavaj, MBA

Softvérový inžinier

Všetky články

O výpadku sa dozviete včas.

Pridajte svoj web alebo API do UpBota a nastavte, komu príde upozornenie.

Začať monitorovať zadarmo