aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorSimon Riggs <simon@2ndQuadrant.com>2010-01-10 15:44:28 +0000
committerSimon Riggs <simon@2ndQuadrant.com>2010-01-10 15:44:28 +0000
commit3bfcccc2954ce251e2aea6503c0d937c493db781 (patch)
tree4f8aa5492ae4baa610027cf97e2b5cd5920a3fb7 /src/backend/commands/dbcommands.c
parent87091cb1f1ed914e2ddca424fa28f94fdf8461d2 (diff)
downloadpostgresql-3bfcccc2954ce251e2aea6503c0d937c493db781.tar.gz
postgresql-3bfcccc2954ce251e2aea6503c0d937c493db781.zip
During Hot Standby, fix drop database when sessions idle.
Previously we only cancelled sessions that were in-transaction. Simple fix is to just cancel all sessions without waiting. Doing it this way avoids complicating common code paths, which would not be worth the trouble to cover this rare case. Problem report and fix by Andres Freund, edited somewhat by me
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index d2e38f631f8..846f59244b4 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.230 2010/01/02 16:57:37 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.231 2010/01/10 15:44:28 sriggs Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1945,22 +1945,27 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
if (InHotStandby)
{
- VirtualTransactionId *database_users;
-
/*
- * Find all users connected to this database and ask them
- * politely to immediately kill their sessions before processing
- * the drop database record, after the usual grace period.
- * We don't wait for commit because drop database is
- * non-transactional.
+ * We don't do ResolveRecoveryConflictWithVirutalXIDs() here since
+ * that only waits for transactions and completely idle sessions
+ * would block us. This is rare enough that we do this as simply
+ * as possible: no wait, just force them off immediately.
+ *
+ * No locking is required here because we already acquired
+ * AccessExclusiveLock. Anybody trying to connect while we do this
+ * will block during InitPostgres() and then disconnect when they
+ * see the database has been removed.
*/
- database_users = GetConflictingVirtualXIDs(InvalidTransactionId,
- xlrec->db_id,
- false);
+ while (CountDBBackends(xlrec->db_id) > 0)
+ {
+ CancelDBBackends(xlrec->db_id);
- ResolveRecoveryConflictWithVirtualXIDs(database_users,
- "drop database",
- CONFLICT_MODE_FATAL);
+ /*
+ * Wait awhile for them to die so that we avoid flooding an
+ * unresponsive backend when system is heavily loaded.
+ */
+ pg_usleep(10000);
+ }
}
/* Drop pages for this database that are in the shared buffer cache */