Skip to content

Commit

Permalink
Try to fix some of the DROP DATABASE flakes (#7907)
Browse files Browse the repository at this point in the history
I think one of the sources of trouble might be that _early_introspection
is hanging on to connections and can't be forced to drop them.
Try to work around it by forcing them closed at the end of introspecting.

Also, when in dev/test mode, dump out all the info about the other
connections.  Hopefully this will let us figure out where they are
coming from.
  • Loading branch information
msullivan authored Oct 23, 2024
1 parent 1074087 commit 15f8088
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions edb/server/tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,7 @@ async def _pg_ensure_database_not_connected(self, dbname: str) -> None:
conns = await pgcon.sql_fetch_col(
b"""
SELECT
pid
row_to_json(pg_stat_activity)
FROM
pg_stat_activity
WHERE
Expand All @@ -1003,8 +1003,14 @@ async def _pg_ensure_database_not_connected(self, dbname: str) -> None:
)

if conns:
debug_info = ""
if self.server.in_dev_mode() or self.server.in_test_mode():
jconns = [json.loads(conn) for conn in conns]
debug_info = ": " + json.dumps(jconns)

raise errors.ExecutionError(
f"database branch {dbname!r} is being accessed by other users"
f"database branch {dbname!r} is being accessed by "
f"other users{debug_info}"
)

@contextlib.asynccontextmanager
Expand Down Expand Up @@ -1222,6 +1228,18 @@ async def _early_introspect_db(self, dbname: str) -> None:
early=True,
)

# Early introspection runs *before* we start accepting tasks.
# This means that if we are one of multiple frontends, and we
# get a ensure-database-not-used message, we aren't able to
# handle it. This can result in us hanging onto a connection
# that another frontend wants to get rid of.
#
# We still want to use the pool, though, since it limits our
# connections in the way we want.
#
# Hack around this by pruning the connection ourself.
await self._pg_pool.prune_inactive_connections(dbname)

async def _introspect_dbs(self) -> None:
async with self.use_sys_pgcon() as syscon:
dbnames = await self._server.get_dbnames(syscon)
Expand Down

0 comments on commit 15f8088

Please sign in to comment.