2010-07-22 8 views
12

Konfiguracja: wiele serwerów WWW, działających mod_wsgi, Apache i pgbouncer, które łączą się z udostępnionym DB z Postgres 8.3.6. Aplikacja uruchamia Django.PostgreSQL Diagnostyka i czytanie w trybie bezczynności pg_locks

Co widzimy: zapytania "bezczynne w transakcji" w DB, które spędzają dużo czasu. Aby je zobaczyć, będę uruchomić coś takiego:

SELECT query_start, procpid, client_addr, current_query FROM pg_stat_activity 
WHERE query_start < NOW() - interval '5 minutes'; 

Większość Wyniki oczywiście to tylko bezczynne połączenia że pgbouncer utrzymuje otwarte do użytku, ale czasami nie będą te stare „transakcja” IDLE w zapytaniach . Rozumiem, że oznacza to, że istnieje transakcja zapytania, która czeka na coś lub coś, co miało BEGIN, ale nie osiągnęło COMMIT lub ROLLBACK.

Moim następnym krokiem było spróbować użyć pg_locks celu określenia, jakie proces czeka na:

select pg_class.relname, pg_locks.transactionid, pg_locks.mode, 
     pg_locks.granted as "g", pg_stat_activity.current_query, 
     pg_stat_activity.query_start, 
     age(now(),pg_stat_activity.query_start) as "age", 
     pg_stat_activity.procpid 
from pg_stat_activity,pg_locks 
left outer join pg_class on (pg_locks.relation = pg_class.oid) 
where pg_locks.pid=pg_stat_activity.procpid 
and pg_stat_activity.procpid = <AN IDLE TRANSACTION PROCESS> 
order by query_start; 

wiele razy, wynik dostaję wygląda tak:

relname | transactionid |  mode  | g |  current_query  |   query_start   |  age  | client_addr | procpid 
---------+---------------+-----------------+---+-----------------------+------------------------------+-----------------+----------------+--------- 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | ExclusiveLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
     |    | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 | 1991 
(10 rows) 

I nie jestem pewien, jak to czytać (myślę, że wynika to z niezupełnie zrozumienia pg_locks). Nie ma nazwy, więc czy mówi, że czeka na nic? Pomyślałem, że jeśli przyznano, że jest "prawdziwe", miało ono zamek. Ponieważ wszystkie te wyniki są przyznane, czy pg_locks pokazuje mi, jakie blokady mają, a nie to, na co czeka?

W tej chwili "naprawiam" to, restartując Apache, który wydaje się potrząsać transakcjami, ale oczywiście to nie jest prawdziwe rozwiązanie. Szukam Postgresa, aby dać mi miejsce, w którym chciałbym to rozgryźć, zwłaszcza, że ​​Django powinien automatycznie zarządzać swoimi połączeniami i transakcjami.

+1

Dosyć prawdopodobnym powodem, dla którego nie widzisz niczego w nazwie, jest to, że jesteś podłączony do niewłaściwej bazy danych. Połączenie, które uruchamia kwerendę, musi być połączone z tym samym dbem, którego dotyczy relacja, lub nie będzie w stanie podać nazwy. Zgaduję, że jesteś podłączony do bazy danych "postgres", lub tak podczas uruchamiania kwerendy ... –

Odpowiedz

3

Dla Django konkretnie, ten wpis szczegóły dlaczego widzisz ten problem:

Threaded Django task...

mówię „specyficznie” tutaj, ponieważ prawdziwym problemem jest Ramki web/drivers/ORMs pracujący cały czas w transakcji w trybie (i czasami wywoływanie wycofywania po każdym freakin 'zapytaniu SELECT), kiedy naprawdę powinny działać w trybie automatycznego zatwierdzania i obsługiwać potrzeby transakcji tylko w razie potrzeby. Moduł utrwalania PostgreSQL Apache :: Sessions był katastrofą (co najmniej kilka lat temu), ponieważ zamykał transakcje tylko wtedy, gdy był zbierany. Yikes!

+0

Jak rozumiem, jeden okazał, że musiał ręcznie zamknąć połączenia tylko w kontekście zaplanowanych zadań cron, tj. gdzie sygnał zamknięcia połączenia Django, który jest uruchamiany, gdy żądanie jest wykonane, nie jest zaangażowany. Te bezczynne transakcje pochodzą z serwerów sieci Web, na których nie działają żadne procesy Crons/independent Django. – KRH