summaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorSimon Riggs2010-01-16 14:16:31 +0000
committerSimon Riggs2010-01-16 14:16:31 +0000
commit8bfd1a88486f340503da610e762c089336cada36 (patch)
treee2932c33d3efdbe6db07370c2043283b0292fab1 /src/backend/commands/dbcommands.c
parent40b91b3a8ddf4a7742051ee384ac94b30d8136c9 (diff)
Lock database while running drop database in Hot Standby to protect
against concurrent reconnection. Failure during testing showed issue was possible, even though earlier analysis seemed to indicate it would not be required. Use LockSharedObjectForSession() before ResolveRecoveryConflictWithDatabase() and hold lock until end of processing for that WAL record. Simple approach to avoid introducing further bugs at this stage of development on an improbable issue.
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index a45b351dd54..320c1773b85 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.232 2010/01/14 11:08:00 sriggs Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.233 2010/01/16 14:16:31 sriggs Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1944,7 +1944,15 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
if (InHotStandby)
+ {
+ /*
+ * Lock database while we resolve conflicts to ensure that InitPostgres()
+ * cannot fully re-execute concurrently. This avoids backends re-connecting
+ * automatically to same database, which can happen in some cases.
+ */
+ LockSharedObjectForSession(DatabaseRelationId, xlrec->db_id, 0, AccessExclusiveLock);
ResolveRecoveryConflictWithDatabase(xlrec->db_id);
+ }
/* Drop pages for this database that are in the shared buffer cache */
DropDatabaseBuffers(xlrec->db_id);
@@ -1960,6 +1968,17 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
ereport(WARNING,
(errmsg("some useless files may be left behind in old database directory \"%s\"",
dst_path)));
+
+ if (InHotStandby)
+ {
+ /*
+ * Release locks prior to commit. XXX There is a race condition here that may allow
+ * backends to reconnect, but the window for this is small because the gap between
+ * here and commit is mostly fairly small and it is unlikely that people will be
+ * dropping databases that we are trying to connect to anyway.
+ */
+ UnlockSharedObjectForSession(DatabaseRelationId, xlrec->db_id, 0, AccessExclusiveLock);
+ }
}
else
elog(PANIC, "dbase_redo: unknown op code %u", info);