Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3bfcccc

Browse files
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
1 parent 87091cb commit 3bfcccc

File tree

3 files changed

+48
-16
lines changed

3 files changed

+48
-16
lines changed

src/backend/commands/dbcommands.c

+19-14
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.230 2010/01/02 16:57:37 momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.231 2010/01/10 15:44:28 sriggs Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -1945,22 +1945,27 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
19451945

19461946
if (InHotStandby)
19471947
{
1948-
VirtualTransactionId *database_users;
1949-
19501948
/*
1951-
* Find all users connected to this database and ask them
1952-
* politely to immediately kill their sessions before processing
1953-
* the drop database record, after the usual grace period.
1954-
* We don't wait for commit because drop database is
1955-
* non-transactional.
1949+
* We don't do ResolveRecoveryConflictWithVirutalXIDs() here since
1950+
* that only waits for transactions and completely idle sessions
1951+
* would block us. This is rare enough that we do this as simply
1952+
* as possible: no wait, just force them off immediately.
1953+
*
1954+
* No locking is required here because we already acquired
1955+
* AccessExclusiveLock. Anybody trying to connect while we do this
1956+
* will block during InitPostgres() and then disconnect when they
1957+
* see the database has been removed.
19561958
*/
1957-
database_users = GetConflictingVirtualXIDs(InvalidTransactionId,
1958-
xlrec->db_id,
1959-
false);
1959+
while (CountDBBackends(xlrec->db_id) > 0)
1960+
{
1961+
CancelDBBackends(xlrec->db_id);
19601962

1961-
ResolveRecoveryConflictWithVirtualXIDs(database_users,
1962-
"drop database",
1963-
CONFLICT_MODE_FATAL);
1963+
/*
1964+
* Wait awhile for them to die so that we avoid flooding an
1965+
* unresponsive backend when system is heavily loaded.
1966+
*/
1967+
pg_usleep(10000);
1968+
}
19641969
}
19651970

19661971
/* Drop pages for this database that are in the shared buffer cache */

src/backend/storage/ipc/procarray.c

+27-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.54 2010/01/02 16:57:51 momjian Exp $
40+
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.55 2010/01/10 15:44:28 sriggs Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -1826,6 +1826,32 @@ CountDBBackends(Oid databaseid)
18261826
return count;
18271827
}
18281828

1829+
/*
1830+
* CancelDBBackends --- cancel backends that are using specified database
1831+
*/
1832+
void
1833+
CancelDBBackends(Oid databaseid)
1834+
{
1835+
ProcArrayStruct *arrayP = procArray;
1836+
int index;
1837+
1838+
/* tell all backends to die */
1839+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1840+
1841+
for (index = 0; index < arrayP->numProcs; index++)
1842+
{
1843+
volatile PGPROC *proc = arrayP->procs[index];
1844+
1845+
if (proc->databaseId == databaseid)
1846+
{
1847+
proc->recoveryConflictMode = CONFLICT_MODE_FATAL;
1848+
kill(proc->pid, SIGINT);
1849+
}
1850+
}
1851+
1852+
LWLockRelease(ProcArrayLock);
1853+
}
1854+
18291855
/*
18301856
* CountUserBackends --- count backends that are used by specified user
18311857
*/

src/include/storage/procarray.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.28 2010/01/02 16:58:08 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.29 2010/01/10 15:44:28 sriggs Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -63,6 +63,7 @@ extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid,
6363

6464
extern int CountActiveBackends(void);
6565
extern int CountDBBackends(Oid databaseid);
66+
extern void CancelDBBackends(Oid databaseid);
6667
extern int CountUserBackends(Oid roleid);
6768
extern bool CountOtherDBBackends(Oid databaseId,
6869
int *nbackends, int *nprepared);

0 commit comments

Comments
 (0)