Здається, у вашому додатку витік з’єднання, оскільки він не може закрити об’єднані з’єднання . У вас виникають проблеми не лише із <idle> in transaction
сеансами, але й із загальною кількістю зв’язків.
Вбивство зв’язків - це не правильна відповідь, але це тимчасовий обхідний спосіб.
Замість того, щоб повторно запускати PostgreSQL для завантаження всіх інших з'єднань з бази даних PostgreSQL, див.: Як я можу від'єднати всіх інших користувачів від бази даних postgres? та Як скинути базу даних PostgreSQL, якщо до неї є активні підключення? . Останній показує кращий запит.
Для встановлення тайм-аутів, як запропонував @Doon, див. Розділ Як автоматично закрити недіючі з’єднання в PostgreSQL? , який радить вам використовувати PgBouncer для проксі для PostgreSQL та керування простоями з'єднань. Це дуже гарна ідея, якщо у вас є програма для виправлення помилок, яка все одно витікає з підключень; Я настійно рекомендую налаштувати PgBouncer.
TCP KeepAlive не робитиме цю роботу тут, тому що додаток все ще підключений і живий, він просто не повинно бути.
У PostgreSQL 9.2 і вище ви можете використовувати новий state_change
стовпець часової позначки та state
поле pg_stat_activity
для реалізації неробочого з’єднання. Попросіть роботу cron виконати щось подібне:
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;
У старих версіях потрібно застосовувати складні схеми, які відстежують час простою з’єднання. Не докучай; просто використовуйте pgbouncer.