Ответ 1
Похоже, что у вас есть утечка соединения в вашем приложении, потому что он не может закрыть пул соединений. У вас возникают проблемы не только с <idle> in transaction
сеансах <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.