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