Comment faire pour supprimer une base de données PostgreSQL si il y a des connexions actives à elle?
J'ai besoin d'écrire un script qui fera tomber une base de données PostgreSQL. Il peut y avoir un grand nombre de connexions, mais le script doit en tenir compte.
La norme DROP DATABASE db_name
requête ne fonctionne pas quand il y a des connexions ouvertes.
Comment puis-je résoudre le problème?
- Quelle est la version de PostgreSQL êtes-vous?
- J'utilise PostgreSQL 8.4
- Problème: Alors que vous pouvez tuer les sessions connectées à la base de données, ils peuvent se reconnecter si rapidement que vous ne pouvez toujours pas supprimer la base de données. Heureusement ce post montre comment lock-out, de nouvelles connexions, de sorte que vous pouvez tuer les connexions en cours et supprimer la base de données selon le plan: dba.stackexchange.com/questions/11893/...
- J'ai trouvé cette réponse sur dba.stackexchange être très utile dba.stackexchange.com/a/11895/163539 -- succincte mais suffisamment explicites.
Vous devez vous connecter pour publier un commentaire.
Cela supprime les connexions existantes, sauf pour le vôtre:
Requête
pg_stat_activity
et obtenir le pid valeurs que vous voulez tuer, puis le problèmeSELECT pg_terminate_backend(pid int)
à eux.PostgreSQL 9.2 et ci-dessus:
PostgreSQL 9.1 et ci-dessous:
Une fois que vous vous déconnectez tout le monde, vous devez le déconnecter et de le problème de la CHUTE de commande de BASE de données à partir d'une connexion à partir d'une autre base de données aka pas celui de votre tentative de drop.
Remarque le changement de nom de la
procpid
colonne depid
. Voir cette liste de discussion thread.; drop database TARGET_DB;
bien fonctionné dans mon cas, assurez-vous que la db a été fait par le temps, les choses ont commencé une nouvelle tentative.datid
, paspid
pour les versions ultérieurespg_terminate_backend()
a ruineux effets sur pgpool. Utilisationpg_cancel_backend()
si pgpool est dans votre pile. pgpool.net/mediawiki/index.php/...function pg_terminate_backend(integer) does not exist
.Dans PostgreSQL 9.2 et au-dessus, de se déconnecter de tout sauf de votre session à partir de la base de données que vous êtes connecté à:
Dans les anciennes versions c'est la même chose, il suffit de changer
pid
àprocpid
. Pour vous déconnecter d'une base de données différente il suffit de changercurrent_database()
pour le nom de la base de données que vous souhaitez déconnecter des utilisateurs de.Vous pouvez
REVOKE
laCONNECT
droit des utilisateurs de la base de données avant de déconnecter les utilisateurs, sinon les utilisateurs vont juste continuer à se reconnecter et vous n'aurez jamais la chance de tomber à la DB. Voir ce commentaire et la question auquel il est associé, Comment puis-je détacher de tous les autres utilisateurs de la base de données.Si vous voulez juste pour déconnecter les utilisateurs inactifs, voir cette question.
Vous pourriez tuer toutes les connexions avant la suppression de la base de données à l'aide de la
pg_terminate_backend(int)
fonction.Vous pouvez obtenir tous les serveurs d'arrière-plan à l'aide de la vue système
pg_stat_activity
Je ne suis pas entièrement sûr, mais serait probablement tuer toutes les séances:
Bien sûr, vous ne pouvez pas être vous-même connecté à la base de données
J'ai remarqué que postgresql 9.2 appelle désormais la colonne pid plutôt que procpid.
J'ai tendance à l'appeler à partir du shell:
Espère que c'est utile. Grâce à @JustBob pour le sql.
Selon votre version de postgresql, vous pouvez exécuter dans un bug, qui fait
pg_stat_activity
omettre les connexions actives de chuté utilisateurs. Ces connexions sont également non représenté à l'intérieur de pgAdminIII.Si vous faites des tests automatiques (dans lequel vous avez également créer des utilisateurs), cela peut être un scénario probable.
Dans ce cas, vous avez besoin de revenir à des questions comme:
REMARQUE: Dans la version 9.2+ vous aurez changement
procpid
àpid
.procpid
àpid
cet extrait fonctionne sur 9.3.Je viens de redémarrer le service Ubuntu pour déconnecter les clients connectés.
Dans l'Invite de commande Linux, je voudrais tout d'abord arrêter tous postgresql processus en cours d'exécution en liant cette commande
sudo /etc/init.d/postgresql restart
tapez la commande
bg pour vérifier si d'autres postgresql processus sont toujours en cours d'exécution
ensuite suivie par dropdb dbname supprimer la base de données
Cela fonctionne pour moi sur invite de commande linux
PostgreSQL 9.2 et ci-dessus:
SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'
Voici mon hack... =D
J'ai mis cette réponse parce que inclure une commande (ci-dessus) pour bloquer les nouvelles connexions et parce que toute tentative avec la commande...
... ne fonctionne pas à bloquer les nouvelles connexions!
Grâce à @araqnid @GoatWalker ! =D
https://stackoverflow.com/a/3185413/3223785
Dans mon cas, j'ai eu à exécuter une commande à abandonner toutes les connexions, y compris ma connexion administrateur
qui s'est terminé toutes les connexions et de me montrer un mortel "erreur" message :
FATAL: terminating connection due to administrator command SQL state: 57P01
Après qu'il était possible de supprimer la base de données