Postgresql deadlocks

Tomáš Krbec tomas.krbec na gmail.com
Pátek Březen 2 16:12:00 CET 2012


Zdravím,

myslím si, že deadlocky nelze úplně vymýtit, takže je potřeba, aby se
aplikace s nimi dokázala vyrovnat.


S pozdravem
Tomáš Krbec



Dne 1. března 2012 23:28 Tomas Vondra <tv na fuzzy.cz> napsal(a):

> Ahoj,
>
> tohle je hodně "postgresql specific" dotaz, možná by bylo lepší to řešit
> spíš v http://groups.google.com/group/postgresql-cz ...
>
> On 1.3.2012 15:12, Martin Tiršel wrote:
> > Zdravim,
> >
> > mam nad Djangom a Postgresql postavenu aplikaciu a od vcera sa mi zacali
> > (bez zmeny v aplikacii) objavovat deadlocky v PG. Doteraz to za niekolko
> > mesiacov nenastalo, medzitym sa aplikacia prerabala a na novej verzii
> > bezi niekolko tyzdnov. Doteraz nebol jediny problem s tymto. Od vcera
> > kazdych niekolko minut, hoci aplikacia updatovana nebola, len pribudaju
> > nove data v databaze.
>
> Deadlocky souvisí s časováním a jejich pravděpodobnost často závisí
> např. na objemu dat. Málo dat -> zámky jsou drženy jen krátce -> malá
> pravděpodobnost že dojde k deadlocku. No a jak objem dat (nebo využití
> aplikace) roste, zvyšuje se i jejich pravděpodobnost.
>
> Tím nechci říct že to nemůže být chyba v PostgreSQL, ale že to že se
> deadlocky původně neobjevovaly vůbec nemusí znamenat že je to nějakou
> změnou v PostgreSQL (to je spíše nepravděpodobné, protože síla zámků se
> v novějších verzích spíše snižuje).
>
> > Vie ma niekto nasmerovat, na co by som sa mal zamerat, pripadne skusit
> > upravit? Logy vyzeraju nejako takto:
> >
> > 2012-03-01 14:52:27 CET ERROR:  deadlock detected
> > 2012-03-01 14:52:27 CET DETAIL:  Process 10372 waits for ShareLock on
> > transaction 130251607; blocked by process 10370.
> >     Process 10370 waits for ShareLock on transaction 130251610; blocked
> > by process 10372.
> >     Process 10372: UPDATE "advert_advert" SET "views" =
> > "advert_advert"."views" + 1 WHERE "advert_advert"."id" = 1152
> >     Process 10370: UPDATE "advert_advert" SET "views" =
> > "advert_advert"."views" + 1 WHERE "advert_advert"."id" = 1153
> > 2012-03-01 14:52:27 CET HINT:  See server log for query details.
> > 2012-03-01 14:52:27 CET STATEMENT:  UPDATE "advert_advert" SET "views" =
> > "advert_advert"."views" + 1 WHERE "advert_advert"."id" = 1152
>
> Pokud můžete, zaměřte se na pořadí v jakém měníte data. Problém je když
> transakce mění data v různém pořadí (např. jedna transakce nejdříve
> updatne 1152 a druhý 1153 zatím co druhá 1153 a až pak 1152).
>
> > Medzitym  su v logoch tieto zaznamy, ale to s tym zrejme nesuvisi:
> >
> > 2012-03-01 14:54:01 CET LOG:  could not receive data from client:
> > Connection reset by peer
> > 2012-03-01 14:54:01 CET LOG:  unexpected EOF on client connection
> > 2012-03-01 14:54:02 CET LOG:  could not receive data from client:
> > Connection reset by peer
> > 2012-03-01 14:54:02 CET LOG:  unexpected EOF on client connection
> > 2012-03-01 14:56:02 CET LOG:  could not receive data from client:
> > Connection reset by peer
> > 2012-03-01 14:56:02 CET LOG:  unexpected EOF on client connection
> > 2012-03-01 14:56:02 CET LOG:  could not receive data from client:
> > Connection reset by peer
> > 2012-03-01 14:56:02 CET LOG:  unexpected EOF on client connection
>
> Tohle většinou znamená že spadlo spojení (např. kvůli síťové chybě) nebo
> klientská aplikace z nějakého neznámého důvodu spadla aniž by se
> korektně odpojila (tj. buď je programátor čuně a nezavolal "close" nebo
> aplikace např. spadla na segfault).
>
> > Ak zadam tuto query (pripadne dalsie, ktore sa uvadzaju na
> > http://wiki.postgresql.org/wiki/Lock_Monitoring pri rieseni problemo s
> > uzamykanim):
> >
> > select relation::regclass, * from pg_locks where not granted;
> >
> > tak mi to ziadne zaznamy nevrati.
>
> Problém je že tyhle dotazy ukazují "živá data" tj. jak to vypadá právě
> teď - neumožňuje vám to nahlédnout jak to vypadalo v okamžiku deadlocku.
>
> Osobně bych postupoval asi takto:
>
> 1) Základní review kódu - v jakém pořadí se ta data aktualizují (často
>   stačí např. na začátku setřídit data a pak je měnit v tomhle pořadí).
>
> 2) Snaha reprodukovat ten bug na jiném stroji - většinou se ví v rámci
>   jaké transakce to hází chybu, takže stačí např. udělat stress test s
>   velkým počtem klientů a ono k deadlocku dojde i častěji než na
>   produkčním systému. Jakmile máte reprodukovatelný testcase, je to
>   řádově jednodušší opravit (ať už je to aplikační chyba nebo chyba
>   přímo v PostgreSQL).
>
> 3) Pokud předchozí možnosti nepomáhají, nastupuje BRUTUS metoda,
>   spočívající v zapnutí logování všech příkazů. V okamžiku kdy dojde k
>   deadlocku je pak celkem jednoduché vydedukovat z toho kolidující
>   transakce pomocí PID (je třeba to doplnit do log_line_prefix). Tohle
>   ale může být na produkčním systému značná zátěž a současně to může
>   ovlivnit časování tak že k deadlockům nebude docházet.
>
> T.
> _______________________________________________
> Linux mailing list
> Linux na linux.cz
> http://www.linux.cz/mailman/listinfo/linux
>


Další informace o konferenci Linux