Подтвердить что ты не робот

Heroku Postgres: Слишком много связей. Как я могу убить эти соединения?

У меня есть приложение, работающее на Heroku. В этом приложении установлен аддон Postgres 9.2.4 (Dev). Для доступа к моей онлайн-базе данных я использую Navicat Postgres. Иногда Navicat не выполняет чистое соединение, установленное в базе данных Postgres. В результате через некоторое время доступно 20+ открытых подключений к базе данных Postgres. My Postgres устанавливает только 20 одновременных подключений. Таким образом, с 20 + открытыми соединениями моя база данных Postgress теперь недоступна (слишком много соединений).

Я знаю, что это проблема Navicat, и я пытаюсь решить эту проблему с этой целью. Но если это произойдет (слишком много соединений), как я могу это решить (например, закрыть все подключения).

Я пробовал все следующие вещи, без результата.

  • Закрыл Navicat и перезапустил мой компьютер (OS X 10.9)
  • Перезагрузка моего приложения Heroku (heroku restart)
  • Попробовал перезапустить онлайн-базу данных, но я обнаружил, что нет возможности сделать это.
  • Вручную закрыты все подключения из OS X к IP-адресу сервера Postgres
  • Перезагрузили наш маршрутизатор

Я думаю, что очевидно, что есть некоторые "мертвые" связи на стороне Postgres. Но как их закрыть?

4b9b3361

Ответ 2

heroku pg:killall убьет все открытые соединения, но это может быть тупой инструмент для ваших нужд. Интересно, что можно фактически убить определенные соединения, используя heroku dataclips.

Чтобы получить подробный список соединений, вы можете запрашивать данные через dataclips:

SELECT * FROM pg_stat_activity;

В некоторых случаях вам может потребоваться уничтожить все подключения, связанные с IP-адресом (ваш ноутбук или в моем случае, сервер, который был теперь уничтожен).

Вы можете видеть, сколько соединений принадлежит каждому IP-адресу клиента, используя:

SELECT client_addr, count(*) 
FROM pg_stat_activity 
WHERE client_addr is not null 
  AND client_addr <> (select client_addr from pg_stat_activity where pid=pg_backend_Tid()) 
GROUP BY client_addr; 

в котором будет указано количество подключений на каждый IP-адрес, исключая IP-адрес, который использует сам dataclips.

Чтобы действительно убить соединения, вы передаете их "pid" на pg_terminate_backend(). В простом случае:

SELECT pg_terminate_backend(1234)

где 1234 - это оскорбительный PID, который вы обнаружили в pg_stat_activity.

В моем случае я хотел убить все соединения, связанные с (теперь мертвым) сервером, поэтому я использовал:

SELECT pg_terminate_backend(pid), host(client_addr) 
FROM pg_stat_activity 
WHERE host(client_addr) = 'IP HERE'

Ответ 3

Как суперпользователь (например, postgres), вы можете убить каждый сеанс, но ваш текущий с таким запросом:

select pg_cancel_backend(pid)
from pg_stat_activity
where pid <> pg_backend_pid();

Если они не исчезнут, вам, возможно, придется использовать более сильное "убийство", но, конечно, сначала проверьте с помощью pg_cancel_backend().

select pg_terminate_backend(pid)
from pg_stat_activity
where pid <> pg_backend_pid();

Ответ 4

Из документации Heroku (акцент мой):

FATAL: слишком много соединений для роли

FATAL: слишком много соединений для роли "[имя роли]" Это происходит в планах начального уровня (dev и basic), которые имеют максимальный лимит подключения 20 на пользователя. Чтобы устранить эту ошибку, закройте некоторые соединения с вашей базой данных, остановив фоновые работники, уменьшив количество динамиков или перезапустив приложение, если оно со временем созловало утечки. Обсуждение работы с соединениями в Приложение Rails можно найти здесь.

Поскольку Heroku не предоставляет доступ к суперпользователю, ваши варианты ограничены вышеприведенным.