diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index d2e38f631f88b103fe4c3384fcef1670942a9117..846f59244b4b0b70d143f41798d4b1a7cadf76f3 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 */
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index ccaf8420f5daf5ac0db5354a5c780f9b6f7aaf0f..01a7c2123f1534ccda836dd167e7de67bd7e713d 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.54 2010/01/02 16:57:51 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.55 2010/01/10 15:44:28 sriggs Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1826,6 +1826,32 @@ CountDBBackends(Oid databaseid)
 	return count;
 }
 
+/*
+ * CancelDBBackends --- cancel backends that are using specified database
+ */
+void
+CancelDBBackends(Oid databaseid)
+{
+	ProcArrayStruct *arrayP = procArray;
+	int			index;
+
+	/* tell all backends to die */
+	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+
+	for (index = 0; index < arrayP->numProcs; index++)
+	{
+		volatile PGPROC *proc = arrayP->procs[index];
+
+		if (proc->databaseId == databaseid)
+		{
+			proc->recoveryConflictMode = CONFLICT_MODE_FATAL;
+			kill(proc->pid, SIGINT);
+		}
+	}
+
+	LWLockRelease(ProcArrayLock);
+}
+
 /*
  * CountUserBackends --- count backends that are used by specified user
  */
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 2a12a83bd08b5943465fb62dbd2d7e388b4216a5..4572f489af812a91a2e0a0933b0f5c69e6b8f3a0 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.28 2010/01/02 16:58:08 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.29 2010/01/10 15:44:28 sriggs Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,6 +63,7 @@ extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid,
 
 extern int	CountActiveBackends(void);
 extern int	CountDBBackends(Oid databaseid);
+extern void	CancelDBBackends(Oid databaseid);
 extern int	CountUserBackends(Oid roleid);
 extern bool CountOtherDBBackends(Oid databaseId,
 					 int *nbackends, int *nprepared);