1 S postgres 5038 876 0 80 0 - 11962 sk_wai 09:57 ? 00:00:00 postgres: postgres my_app ::1(45035) idle
1 S postgres 9796 876 0 80 0 - 11964 sk_wai 11:01 ? 00:00:00 postgres: postgres my_app ::1(43084) idle
Я их много вижу. Мы пытаемся исправить утечку нашего соединения. Но тем временем мы хотим установить тайм-аут для этих незанятых соединений, возможно, максимум до 5 минут.
postgresql
database-connection
user1012451
источник
источник
socketTimeout
из документа похоже, что это полностью закрывает соединение с БД. Я пытаюсь закрыть каждый холостой ход, и счетчик запускается, как только устанавливается соединение.<IDLE> in transaction
сеанс, оставив сеанс запущенным, но в<IDLE>
состоянии? Другими словами, завершить транзакцию, но не сеанс? (Проголосовано против: неясный вопрос)idle
навсегда, мы спрашиваем, можем ли мы установить тайм-аут для каждого соединения / сеанса (я, честно говоря, не знаю правильной терминологии, извините). Если транзакция занимает 5 минут для обычного веб-приложения, что-то должно быть не так ...Ответы:
Похоже, у вас есть утечка соединения в вашем приложении, потому что оно не может закрыть объединенные соединения . У вас проблемы не только с
<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.
источник
idle
. почему я должен его закрыть.В PostgreSQL 9.6 есть новая опция,
idle_in_transaction_session_timeout
которая должна выполнять то, что вы описываете. Вы можете установить его с помощьюSET
команды, например:SET SESSION idle_in_transaction_session_timeout = '5min';
источник
SET SESSION
предназначен только для текущего сеанса (он вернется к значениям по умолчанию, когда вы откроете новое соединение). Вы также можете установить параметры конфигурации на уровне базы данных, напримерALTER DATABASE SET idle_in_transaction_session_timeout = '5min'
, или используя файлы конфигурации (см. Postgresql.org/docs/current/static/config-setting.html ).В PostgreSQL 9.1 неактивные соединения со следующим запросом. Это помогло мне предотвратить ситуацию, которая потребовала перезапуска базы данных. В основном это происходит с открытыми и некорректными соединениями JDBC.
SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE current_query = '<IDLE>' AND now() - query_start > '00:10:00';
источник
если вы используете postgresql 9.6+, то в вашем postgresql.conf вы можете установить
idle_in_transaction_session_timeout = 30000
(мсек)источник
Возможный обходной путь, позволяющий включить тайм-аут сеанса базы данных без внешней запланированной задачи, - использовать разработанное мной расширение pg_timeout .
источник