npgsql: "database ... is being accessed by other users" error trying to drop database even after disposing of the connection
I create an NpgsqlConnection and do some stuff in a database, then try to drop that database. This fails with
Npgsql.PostgresException : 55006: database "test_settings_637363918866651378" is being accessed by other users
Data:
Severity: ERROR
InvariantSeverity: ERROR
SqlState: 55006
MessageText: database "test_settings_637363918866651378" is being accessed by other users
Detail: Detail redacted as it may contain sensitive data. Specify 'Include Error Detail' in the connection string to include this information.
File: dbcommands.c
Line: 888
Routine: dropdb
at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming)
at Npgsql.NpgsqlDataReader.NextResult()
at Npgsql.NpgsqlCommand.ExecuteReaderAsync(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteNonQuery()
This happens even if I call NpgsqlConnection.ChangeDatabase() to change to another database and even if I call NpgsqlConnection.Dispose() and open a new connection (to the “postgres” database) and try to drop my database through that.
It seems like Npgsql is still holding the connection open, probably due to connection pooling. How do I actually disconnect from the database, so it can be dropped?
Further technical details
Npgsql version: 4.1.4 PostgreSQL version: 12.3 Operating system: Windows 7 x64
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 18 (18 by maintainers)
This is expected and by design, so closing the issue. To stop other users from accessing the database without cleaning the pool use
pg_terminate_backendfrom the script.I think the Close docs are already pretty clear on this point:
It follows pretty clearly that if pooling is on, the physical connection isn’t closed etc.
But I agree that ClearPool and ClearAllPools could benefit from better docs - I’ve added some.
It closes the physical connection only if there’s no pooling. Otherwise, it puts it into the pool. The
NpgsqlConnectionchanges the state too in any case.Thanks! Will take a look.
Here you go:
It exists, take a look at
NpgsqlConnection.ClearPoolwhich closes all idle connections in the pool.Consider the
ChangeDatabasemethod. It just closes the connection, detaches it from the pool and opens it again with the replaced value of theDatabaseconnection string parameter. Other connections in the pool won’t be affected.