Como desanexar todos os outros usuários de um banco de dados postgres?

13

Eu preciso de acesso exclusivo a um banco de dados. É possível usar um comando SQL para "desconectar" todos os outros usuários de um banco de dados postgres. Ou talvez fechando todas as outras conexões e obtendo acesso exclusivo.

Isso é para testes de unidade, e os testes são executados apenas manualmente, portanto não há perigo envolvido. Somente conexões antigas antigas serão afetadas.

Não há outros usuários conectados a esses bancos de dados mais unittest.

As velhas conexões mortas vêm do desenvolvimento. Isso acontece o tempo todo quando um teste que está sendo gravado ou falha não sai limpo.


Se alguém também precisar manter outros usuários bloqueados por um tempo após desconectá-los em um cenário de produção, consulte a resposta de Scott Marlowe abaixo: /dba//a/6184/2024


Veja também esta pergunta semelhante no dba: como descartar todas as conexões em um banco de dados específico sem parar o servidor?

mit
fonte

Respostas:

14

Você pode tentar se conectar ao banco de dados como usuário do postgres e executar:

SELECT pg_terminate_backend( procpid )
FROM pg_stat_activity
WHERE procpid <> pg_backend_pid( )    -- 1. don't terminate your own session
    AND datname =                     -- 2. don't terminate connections to 
    (SELECT datname                   --    other databases in the cluster
       FROM pg_stat_activity
      WHERE procpid = pg_backend_pid( )
    );

atualização Uma consulta ainda melhor se livra da subseleção:

SELECT pg_terminate_backend( procpid )
FROM pg_stat_activity
WHERE procpid <> pg_backend_pid( )
    AND datname = current_database( );
gsiems
fonte
2
não esqueça de REVOGAR as permissões CONNECT, caso contrário, os usuários criarão novas conexões antes de você ter acesso exclusivo.
Frank Heikens
@Frank Heikens - Boa captura. Eu havia digitado o "teste de unidade manual", mas se houver outras pessoas conectando além do indivíduo que está fazendo o teste de unidade, "revogar a conexão em <datname> de ..." seria essencial.
gsiems
No PostgreSQL 9.2, procpidfoi renomeado para pid, então cuidado com isso.
Craig Ringer
Além de fazer um REVOKE com o usuário em questão, eu também tinha que REVOGAR ..... público - algo a ser observado!
David N. Welton 22/10
na 9.3, parece que pg_stat_activity.procpid agora é chamado de pg_stat_activity.pid . trabalhou A-OK caso contrário.
perfil completo de JL Peyret
4

O problema aqui é duplo: primeiro, você precisa desconectar esses usuários; depois, é necessário mantê-los fora do servidor. Em vez de revogar as permissões de conexão, eu normalmente uso o pg_hba.conf para recusar novas conexões de determinadas máquinas e / ou usuários e, em seguida, basta fazer uma parada rápida pg_ctl -m; o pg_ctl começa a eliminar todas as conexões atuais. Com o slony fazendo alterações no DDL, isso é praticamente uma necessidade ou você terá impasses em todo o lugar.

Scott Marlowe
fonte
5
Eu sempre uso uma única função que permite CONNECT e é herdada por todas as outras funções. O REVOKE se conecta a essa única função e pronto. Envolva-o em uma função com pg_terminate_backend () e você estará no controle quando precisar parar todas as conexões atuais.
Frank Heikens