Zdá se, že máte únik připojení ve vaší aplikaci, protože se nezdaří uzavřít sdružená připojení . Problémy nemáte jen s <idle> in transaction
relací, ale celkově s příliš mnoha připojeními.
Zabíjení spojení na to není správnou odpovědí, ale je to v pořádku dočasné řešení.
Namísto opětovného spouštění PostgreSQL za účelem zavedení všech ostatních připojení z databáze PostgreSQL si přečtěte:Jak odpojím všechny ostatní uživatele z databáze postgres? a Jak zrušit databázi PostgreSQL, pokud jsou k ní aktivní připojení? . Druhý ukazuje lepší dotaz.
Pro nastavení časových limitů, jak navrhl @Doon, viz Jak automaticky zavřít nečinná připojení v PostgreSQL?, kde je doporučeno používat PgBouncer k proxy pro PostgreSQL a spravovat nečinná připojení. To je velmi dobrý nápad, pokud máte chybnou aplikaci, která stejně propouští připojení; velmi silně doporučujeme nakonfigurovat PgBouncer.
TCP keepalive tu svou práci neudělá, protože aplikace je stále připojená a aktivní, prostě by neměla být.
V PostgreSQL 9.2 a vyšší můžete použít nový state_change
sloupec časového razítka a state
pole pg_stat_activity
k implementaci nečinného připojení reaper. Nechte úlohu cronu spustit něco takového:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'regress'
AND pid <> pg_backend_pid()
AND state = 'idle'
AND state_change < current_timestamp - INTERVAL '5' MINUTE;
Ve starších verzích musíte implementovat komplikovaná schémata, která sledují, kdy připojení přešlo naprázdno. Neobtěžuj se; stačí použít pgbouncer.