Chaque fois que j'essaie de supprimer une base de données, je reçois:
ERROR: database "pilot" is being accessed by other users
DETAIL: There is 1 other session using the database.
Quand j'utilise:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB';
J'ai mis fin à la connexion à partir de cette base de données, mais si j'essaie de supprimer la base de données, quelqu'un se connecte automatiquement à cette base de données et donne cette erreur. Qu'est-ce qui pourrait faire ça? Personne n'utilise cette base de données, sauf moi.
Vous pouvez empêcher de futures connexions:
REVOKE CONNECT ON DATABASE thedb FROM public;
(et éventuellement d'autres utilisateurs/rôles; voir \l+
dans psql
)
Vous pouvez alors mettre fin à toutes les connexions à cette base de données, sauf la vôtre:
SELECT pid, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = current_database() AND pid <> pg_backend_pid();
Sur les anciennes versions, pid
s'appelait procpid
, vous devrez donc vous en occuper.
Puisque vous avez révoqué les droits CONNECT
, tout ce qui essayait de se connecter automatiquement ne devrait plus pouvoir le faire.
Vous pourrez maintenant supprimer la base de données.
Cela ne fonctionnera pas si vous utilisez des connexions superutilisateur pour des opérations normales, mais si vous le faites, vous devez d'abord résoudre ce problème.
Chaque fois que j'essaie de supprimer une base de données, je reçois:
ERROR: database "pilot" is being accessed by other users
DETAIL: There is 1 other session using the database.
Vous devez d'abord révoquer
REVOKE CONNECT ON DATABASE TARGET_DB FROM public;
Alors utilisez:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB';
Cela fonctionnera sûrement.
Il suffit de vérifier quelle est la connexion, d'où elle vient. Vous pouvez voir tout cela dans:
select * from pg_stat_activity where datname = 'TARGET_DB';
C'est peut-être votre connexion?
J'ai trouvé une solution à ce problème essayez d'exécuter cette commande en terminal
ps -ef | grep postgres
tuer le processus par cette commande
Sudo kill -9 PID
Cela signifie qu'un autre utilisateur accède à la base de données ... Redémarrez simplement le postgresql. Cette commande fera l'affaire
root@kalilinux:~#Sudo service postgresql restart
Puis essayez de déposer la base de données:
postgres=# drop database test_database
Ça fera l'affaire. Bonne codage
Si aucun impact potentiel sur les autres services de votre ordinateur, service postgresql restart
pgAdmin 4 solution en utilisant l'interface utilisateur
Commencez par activer l'activité d'affichage sur le tableau de bord si vous n'avez pas:
File > Preferences > Dashboards > Display > Show Activity > true
Désactivez maintenant tous les processus utilisant la base de données:
Devrait maintenant pouvoir supprimer la base de données.
Dans mon cas, j'utilise AWS Redshift (basé sur Postgres) . Et il semble qu'il n'y ait pas d'autres connexions à la base de données, mais j'obtiens la même erreur.
ERROR: database "XYZ" is being accessed by other users
Dans mon cas, il semble que le cluster de base de données effectue encore certains traitements sur la base de données et, bien qu'il n'y ait aucune autre connexion externe/utilisateur, la base de données est toujours utilisée en interne. J'ai trouvé cela en exécutant ce qui suit:
SELECT * FROM stv_sessions;
Donc, mon hack était d'écrire une boucle dans mon code, en recherchant les lignes contenant le nom de ma base de données. (bien sûr, la boucle n'est pas infinie, et est une boucle assoupie, etc.)
SELECT * FROM stv_sessions where db_name = 'XYZ';
Si des lignes sont trouvées, supprimez chaque PID, un par un.
SELECT pg_terminate_backend(PUT_PID_HERE);
Si aucune ligne trouvée, continuez pour supprimer la base de données
DROP DATABASE XYZ;
Remarque: Dans mon cas, j'écris des tests d'unité/système Java, dans lesquels cela pourrait être considéré comme acceptable. Ce n'est pas acceptable pour le code de production.
Voici le hack complet, en Java (ignorer mes classes de test/utilitaire).
int i = 0;
while (i < 10) {
try {
i++;
logStandardOut("First try to delete session PIDs, before dropping the DB");
String getSessionPIDs = String.format("SELECT stv_sessions.process, stv_sessions.* FROM stv_sessions where db_name = '%s'", dbNameToReset);
ResultSet resultSet = databaseConnection.execQuery(getSessionPIDs);
while (resultSet.next()) {
int sessionPID = resultSet.getInt(1);
logStandardOut("killPID: %s", sessionPID);
String killSessionPID = String.format("select pg_terminate_backend(%s)", sessionPID);
try {
databaseConnection.execQuery(killSessionPID);
} catch (DatabaseException dbEx) {
//This is most commonly when a session PID is transient, where it ended between my query and kill lines
logStandardOut("Ignore it, you did your best: %s, %s", dbEx.getMessage(), dbEx.getCause());
}
}
//Drop the DB now
String dropDbSQL = String.format("DROP DATABASE %s", dbNameToReset);
logStandardOut(dropDbSQL);
databaseConnection.execStatement(dropDbSQL);
break;
} catch (MissingDatabaseException ex) {
//ignore, if the DB was not there (to be dropped)
logStandardOut(ex.getMessage());
break;
} catch (Exception ex) {
logStandardOut("Something went wrong, sleeping for a bit: %s, %s", ex.getMessage(), ex.getCause());
sleepMilliSec(1000);
}
}
Aussi simple que cela
Sudo service postgresql restart
Même si j’ai trouvé les deux réponses top-votées utiles à d’autres occasions, aujourd’hui, le moyen le plus simple de résoudre le problème était de réaliser que PyCharm pouvait garder une session ouverte. Si je cliquais sur Stop
dans PyCharm, cela pourrait aider. Avec pgAdmin4 ouvert dans le navigateur, je l’ai fait et j'ai presque immédiatement vu les statistiques des sessions de la base de données tomber à 0, ce qui m'a permis de supprimer la base de données.
En terminal essayez cette commande:
ps -ef | grep postgres
vous verrez comme:
501 1445 3645 0 00:05 0: 00.03 postgres: sasha nombase [local] inactif
Le troisième numéro (3645) est PID.
Vous pouvez supprimer ceci
Sudo kill -9 3645
Et après cela, démarrez votre connexion PostgreSQL.
Démarrer manuellement:
pg_ctl -D /usr/local/var/postgres start