Nel mio caso, sto usando AWS Redshift (basato su Postgres). E sembra che non ci siano altre connessioni al DB, ma sto ottenendo lo stesso errore.
ERROR: database "XYZ" is being accessed by other users
Nel mio caso, sembra che il cluster di database stia ancora eseguendo alcune elaborazioni sul database e, sebbene non vi siano altre connessioni esterne / utente, il database è ancora in uso internamente. Ho trovato questo eseguendo il seguente:
SELECT * FROM stv_sessions;
Quindi il mio hack è stato quello di scrivere un ciclo nel mio codice, cercando le righe con il mio nome di database all'interno. (ovviamente il ciclo non è infinito, ed è un ciclo assonnato, ecc.)
SELECT * FROM stv_sessions where db_name = 'XYZ';
Se vengono rilevate righe, procedere con l'eliminazione di ogni PID, uno per uno.
SELECT pg_terminate_backend(PUT_PID_HERE);
Se non viene trovata alcuna riga, procedere con l'eliminazione del database
DROP DATABASE XYZ;
Nota: nel mio caso, sto scrivendo test di unità / sistema Java, dove questo potrebbe essere considerato accettabile. Questo non è accettabile per il codice di produzione.
Ecco l'hack completo, in Java (ignora le mie classi test / utility).
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);
}
}
GRANT CONNECT ON DATABASE thedb TO public;