NationalSecurityAgency/ghidra · error · SQLException

database in use

Error message

database in use

What it means

Thrown by PostgresFunctionDatabase.dropDatabase() as a precondition check before dropping. If the database status is Busy (an operation is in progress) or there are active connections (postgresDs.getActiveConnections() != 0), the drop is refused to avoid corrupting in-flight work.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/PostgresFunctionDatabase.java:247

				// database integrity should still be recoverable)
				if (asynchronous) {
					st.executeUpdate("SET SESSION synchronous_commit TO OFF");
				}
				else {
					st.executeUpdate("SET SESSION synchronous_commit to ON");
				}
			}
		}
		catch (final SQLException err) {
			throw new SQLException("Could not create database: " + err.getMessage());
		}
	}

	@Override
	protected void dropDatabase() throws SQLException {

		if (getStatus() == Status.Busy || postgresDs.getActiveConnections() != 0) {
			throw new SQLException("database in use");
		}

		BSimServerInfo serverInfo = postgresDs.getServerInfo();
		BSimServerInfo defaultServerInfo =
			new BSimServerInfo(DBType.postgres, serverInfo.getUserInfo(),
				serverInfo.getServerName(), serverInfo.getPort(), DEFAULT_DATABASE_NAME);

		BSimPostgresDataSource defaultDs =
			BSimPostgresDBConnectionManager.getDataSource(defaultServerInfo);
		if (getStatus() == Status.Ready) {
			defaultDs.initializeFrom(postgresDs);
		}

		close(); // close this instance

		try (Connection defaultDb = defaultDs.getConnection();
				Statement defaultSt = defaultDb.createStatement()) {
			StringBuilder sb = new StringBuilder("SELECT 1 FROM pg_database WHERE datname= ");

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Call close() on all FunctionDatabase / connection handles and ensure no concurrent operations are running before dropping.
  2. Wait for in-flight queries to complete or cancel them.
  3. Verify postgresDs.getActiveConnections() returns 0 and getStatus() is not Busy before calling dropDatabase().

Example fix

// before
db.dropDatabase(); // throws "database in use" if connections open

// after
db.close();
// ensure no other thread holds a connection
if (db.getStatus() != Status.Busy && db.getActiveConnections() == 0) {
    db.dropDatabase();
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure no active connections before dropping
db.close();
if (db.getStatus() == Status.Busy) {
    throw new IllegalStateException("Database is busy; cannot drop now");
}
// verify externally that no other process holds a connection

Try / catch

try {
    db.dropDatabase();
} catch (SQLException e) {
    if (e.getMessage().equals("database in use")) {
        // close all connections, wait for operations to finish, then retry
        db.close();
        // retry after ensuring zero active connections
    } else throw e;
}

Prevention

When it happens

Trigger: Calling dropDatabase() while another thread or process holds an open connection to the database, or while the database's own status is Status.Busy. The guard fires before any DROP DATABASE SQL is issued.

Common situations: A concurrent query or ingest is running against the database. A connection pool still holds open connections that have not been released. The application did not call close() on all database handles before attempting to drop. A previous operation left the status in Busy.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/6dd82cd900a7aa07. Report an issue: GitHub.