En mi caso, estoy usando AWS Redshift (basado en Postgres). Y parece que no hay otras conexiones a la base de datos, pero estoy recibiendo este mismo error.
ERROR: database "XYZ" is being accessed by other users
En mi caso, parece que el clúster de la base de datos todavía está procesando algo en la base de datos, y aunque no hay otras conexiones externas / de usuario, la base de datos todavía está en uso interno. Encontré esto ejecutando lo siguiente:
SELECT * FROM stv_sessions;
Entonces, mi truco fue escribir un bucle en mi código, buscando filas con el nombre de mi base de datos. (por supuesto, el bucle no es infinito, y es un bucle adormecido, etc.)
SELECT * FROM stv_sessions where db_name = 'XYZ';
Si se encuentran filas, proceda a eliminar cada PID, uno por uno.
SELECT pg_terminate_backend(PUT_PID_HERE);
Si no se encuentran filas, proceda a descartar la base de datos.
DROP DATABASE XYZ;
Nota: en mi caso, estoy escribiendo pruebas de unidad / sistema Java, donde esto podría considerarse aceptable. Esto no es aceptable para el código de producción.
Aquí está el hack completo, en Java (ignore mis clases de prueba / utilidad).
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;