Postgresql deadlocks

Martin Tiršel lk na blackpage.eu
Pátek Březen 2 19:54:15 CET 2012


Zdravim,

On Thu, 01 Mar 2012 23:28:43 +0100, Tomas Vondra <tv na fuzzy.cz> wrote:

> Ahoj,
>
> tohle je hodně "postgresql specific" dotaz, možná by bylo lepší to řešit
> spíš v http://groups.google.com/group/postgresql-cz ...
>

asi ano, ale nechcel som teraz riesit milion prvu registraciu do dalsieho  
mailing listu/groupy kvoli jednemu prispevku a skor som cakal, ze sa to  
bude viac tykat konfiguracie nez vseobecnych postupov ako pracovat s db :)


> 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).
>

Zistujem, ze to suvisi s poctom dotazov na databazu pri danej vzorke dat,  
viz nizsie.

>> 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).
>

Ano, je to tym, ze si transakcie prepisuju rovnake dat. Ide o to, ze sa  
prevedie nahodny vyber 2-3 inzeratov a tym sa updatne view counter, lenze  
v rovnakej chvili dojde k vyberu dalsich 2-3 inzeratov v ramci dalsej  
transakcie, kde jeden alebo viacero inzeratov je s rovnakym ID ako u prvej  
transakcie.

Vyriesil by to asi SELECT FOR UPDATE, co by blokovalo ine transakcie, ale  
to by mohlo mat negativny dopad na vykon a skalovatelnost. Kolega navrhuje  
pouzit memcached, tam drzat countery a treba raz za minutu zapisat, co mne  
sa velmi nepaci. Zrejme to budem riesit dalsou tabulkou, kde sa kazde  
zobrazenie zapise ako insert, v urcitych intervaloch budem robit prepocty  
a sucasny view stlpec pouzijem len ako cache.


>> 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).
>

Malo by to byt medzi dvomi virtualmi, tkaze siet by som vylucil a django  
nemyslim, ze bude prasacky napisane :) Da sa tych informacii do logu  
vypisat viacej upravenim niektoreho parametru configu?

>> 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.

Vdaka za rady, nejake testovacie prostredie si budem musiet tak ci tak do  
buducna pripravit a pred nasadenim do produkcie prejst niekolkymi urovnami  
testov.



-- 
S pozdravom,
Martin Tiršel


Další informace o konferenci Linux