Come posso staccare tutti gli altri utenti da un database postgres?


13

Ho bisogno dell'accesso esclusivo a un database. È possibile usare un comando SQL per "staccare" tutti gli altri utenti da un database postgres. O forse chiudendo tutte le altre connessioni e quindi ottenendo l'accesso esclusivo.

Questo è per test unitari e i test vengono eseguiti solo manualmente, quindi non vi è alcun pericolo. Solo le vecchie connessioni morte saranno interessate.

Non ci sono altri utenti che si collegano a questi database unittest.

Le vecchie connessioni morte vengono dallo sviluppo. Questo succede sempre quando un test che viene scritto o fallito non esce pulito.


Se qualcuno deve anche tenere gli altri utenti bloccati per un po 'dopo averlo disconnesso in uno scenario di produzione, vedere la risposta di Scott Marlowe di seguito: /dba//a/6184/2024


Vedi anche questa domanda simile su dba: come eliminare tutte le connessioni a un database specifico senza arrestare il server?

Risposte:


14

Potresti provare a connetterti al database come utente postgres ed eseguire:

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( )
    );

aggiornamento Una query ancora migliore elimina la selezione secondaria:

SELECT pg_terminate_backend( procpid )
FROM pg_stat_activity
WHERE procpid <> pg_backend_pid( )
    AND datname = current_database( );

2
non dimenticare di revocare le autorizzazioni CONNECT, altrimenti gli utenti creano nuove connessioni prima di avere accesso esclusivo.
Frank Heikens,

@Frank Heikens - Buona cattura. Avevo digitato "test unitario manuale" ma se ci sono altri collegamenti oltre all'individuo che esegue il test unitario, "revoke connect on <datname> from ..." sarebbe essenziale.
gsiems,

In PostgreSQL 9.2, è procpidstato rinominato in pid, quindi fai attenzione.
Craig Ringer,

Oltre a fare un REVOKE con l'utente in questione, ho dovuto anche REVOKE ..... public - qualcosa a cui prestare attenzione!
David N. Welton,

il 9.3 sembra che pg_stat_activity.procpid sia ora chiamato pg_stat_activity.pid . ha funzionato A-OK altrimenti.
JL Peyret,

4

Il problema qui è duplice, prima devi disconnettere quegli utenti, e in secondo luogo devi tenerli fuori dal tuo server. Invece di revocare i permessi di connessione, di solito uso pg_hba.conf per rifiutare nuove connessioni da determinate macchine e / o utenti, quindi faccio semplicemente un arresto rapido di pg_ctl -m; pg_ctl inizia a eliminare tutte le connessioni correnti. Con slony che fa modifiche al DDL, questo è praticamente una necessità o otterrai deadlock dappertutto.


5
Uso sempre un singolo ruolo che consente CONNECT ed è ereditato da tutti gli altri ruoli. REVOKE si connette per questo singolo ruolo e il gioco è fatto. Avvolgilo in una funzione con pg_terminate_backend () e avrai il controllo quando devi interrompere tutte le connessioni correnti.
Frank Heikens,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.