Sziasztok!
Van egy Qt-ben megírt programom, és valamit elkutyultam az adatbázis tranzakciókezelésében.
Több példány fut a programból, és az init fázisban néha mindegyik megáll mint a szög. Az a log-okból kiderül, hogy mindegyik egy tranzakción belül fagy meg, ha jól értelmezem a jelenséget egymásra várnak.
Hogyan lehet kideríteni, hogy pontosan mi az amire várnak?
- 1322 megtekintés
Hozzászólások
statement_timeout/lock_timeout beállítás postgresql.conf talán segít
- A hozzászóláshoz be kell jelentkezni
Köszi ezt megtaláltam, csak szerettem volna tudni mi akad össze, mielőtt ténylegesen beállítom.
Amúgy lehet hogy (egyelőre) tárgytalan, mert most nem akar lefagyni.
- A hozzászóláshoz be kell jelentkezni
A postgresql doksiban azt írják, hogy nem javasolt a postgresql.conf -ban beállítani a statement_timeout és loc_timeout -ot.
Én most kiadtam az adatbázis megnyitása után a "SET lock_timeout TO 15000" parancsot (ott van a programok logjában). Ezek után, ha deadlock van, vár a végtelenségig. Az összes lekérdező program lefagy, a GUI program meg fut vígan ugyanazon az adatbázison ugyanazzal az API-val (https://github.com/csikfer/lanview2).
Akkor most mi a túró van?
- A hozzászóláshoz be kell jelentkezni
Lehet hogy most lenne itt az ideje deadlock-ot keresni :D
- A hozzászóláshoz be kell jelentkezni
Nem vitatom, hogy jó lenne megtalálni a deadlock okát, de! Itt most legszívesebben azt írnám: "A pgadmin3-nál kreténebb programhoz még nem nagyon volt szerencsém", de maradjunk annyiban az én gondolkodásmódom nagyon messze áll az adatbázis guruk gondolkodásmódjától (nem először szapulom a pgadmin3-at, és már kaptam a pofámra). A lentebb javasolt funkciók például nem működnek, gondolom valami említésre sem érdemes, de létfontosságú lépést kihagytam, vagy már megint egy használhatatlan verzió van az ubuntu repóban.
Másfelől ha nem én vagyok a világon az első, aki teljesen hibátlan (nem pár soros) programot ír, akkor a time-out-okra szükség lesz, és a fenti kérdés erre vonatkozott.
- A hozzászóláshoz be kell jelentkezni
Adatbázisban állítsd be a loggolást, illetve a következő linkeket pörgesd végig:
https://wiki.postgresql.org/wiki/Lock_Monitoring
http://raghavt.blogspot.hu/2011/11/deadlocks-in-postgresql.html
http://big-elephants.com/2013-09/exploring-query-locks-in-postgres/
- A hozzászóláshoz be kell jelentkezni
Kösz, de tartok tőle, hogy ehhez kevés vagyok mint macisajtban a brummogás.
Egy lekérdezésre mondja, hogy vár. Hogy mire az nem derül ki, mert csak egy számként hivatkozik rá, meg a paraméterekkel. Hogy miért áll pont egy olyan tábla olvasásánál (id alapján olvasna egy rekordot), amit szerintem nem ír senki, az számomra szintén nem világos.
Ráadásul a GUI-t elindítva azt a táblát, ami miatt elakadt 7db. lekérdező program, simán olvassa, és írja is.
(Azért nem sikerült egy darabig előállítani a deadlock-ot, mert gyorsan követte a leállítást az újraindítás, így lefutott az összes init, mielőtt bármelyik időzített lekérdezés elindult volna, és nem is akadtak össze.)
Inkább próbálkozok a time-out beállítással, az amúgy sem árt.
- A hozzászóláshoz be kell jelentkezni
Érdemes megnézni a kapcsolatokat. Ezt a PgAdmin 3-ban a Tools menü / server status menüpontjában tudod megtenni. (Illetve szerintem shellből is le tudod kérdezni.) A PgAdmin 4-ben szerintem még nem működik ez a "tool".
A lényeg: Itt láthatod ki kit blokkol. Látod az utolsó lekérdezést. Az is lehet, hogy idle in transactions-t látsz. Akkor nincs lezárva a tranzakciód és ez okozza a gondot.
- A hozzászóláshoz be kell jelentkezni
wow, köszi, ezt nem is tudtam, eddig mindig kézzel vadásztam ezeket az adatokat!
- A hozzászóláshoz be kell jelentkezni
Ezek rajtam nem segítettek. Úgy tűnik én és a postgresql fejlesztői más fogalomrendszert használunk. Jelen esetben 7 program futott (volna), kettő két szálon. A szerver szerint egy példány várakozott lock miatt, kettő éppen nem csinált semmit (a saját event-loop-jában várakozott), és a többinél pedig: 'idle in transaction'. De ez utóbbiak is egy SQL query-ben várakoztak. És mivel ezek az SQL szerint nem lock-ban várakoztak, a lock time-out sem vonatkozott rájuk, az az egy ami szerinte is lock-ban várt pont egy thread volt, amikre meg elfelejtettem beállítani a time-out-ot.
Javítva a thread-eknél lefelejtett time-out állítást, már kaptam rendes hibaüzenetet, és ebből kiderült mi a hiba. Még véletlenül sem az amit a SQL szerverből az álló programok állapota alapján ki lehetett szedni. Ott egy olyan query-ben állt, amit a GUI-n kívül nem ír senki, mindenki csak olvas. A hiba (így utólag elég triviális), a lekérdezések státusz állításánál volt. A megakadó szál a lejárt állapotú rekordok állapotát állítgatta ismeretlenre (egy tranzakcióban, jó sokat), miközben a lekérdezések elindultak, és be akarták állítani az aktuális állapotokat. Persze ez alapján még nem világos pontosan mi állította meg a lock-olt példányt, de a státusz állításnak van néhány következménye: log rekord írás, riasztás kezelés stb., vagyis matat egy pár táblában, de úgy gondolom javítható a hiba így is.
- A hozzászóláshoz be kell jelentkezni