aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
authorSimon Riggs <simon@2ndQuadrant.com>2010-02-13 01:32:20 +0000
committerSimon Riggs <simon@2ndQuadrant.com>2010-02-13 01:32:20 +0000
commitb95a720a487b5027af1b9e4a12542800598ff5de (patch)
treed49548ca497e8169d9cbae7f7127f4f73330f0a5 /src/backend/tcop/postgres.c
parentfafa374f2d1e04ab265d56cdadb634124364646f (diff)
downloadpostgresql-b95a720a487b5027af1b9e4a12542800598ff5de.tar.gz
postgresql-b95a720a487b5027af1b9e4a12542800598ff5de.zip
Re-enable max_standby_delay = -1 using deadlock detection on startup
process. If startup waits on a buffer pin we send a request to all backends to cancel themselves if they are holding the buffer pin required and they are also waiting on a lock. If not, startup waits until max_standby_delay before cancelling any backend waiting for the requested buffer pin.
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 35a4d087ce7..8d33000e616 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.587 2010/01/23 17:04:05 sriggs Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.588 2010/02/13 01:32:19 sriggs Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -2278,6 +2278,9 @@ errdetail_recovery_conflict(void)
case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT:
errdetail("User query might have needed to see row versions that must be removed.");
break;
+ case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:
+ errdetail("User transaction caused buffer deadlock with recovery.");
+ break;
case PROCSIG_RECOVERY_CONFLICT_DATABASE:
errdetail("User was connected to a database that must be dropped.");
break;
@@ -2754,6 +2757,15 @@ RecoveryConflictInterrupt(ProcSignalReason reason)
RecoveryConflictReason = reason;
switch (reason)
{
+ case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:
+ /*
+ * If we aren't waiting for a lock we can never deadlock.
+ */
+ if (!IsWaitingForLock())
+ return;
+
+ /* Intentional drop through to check wait for pin */
+
case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN:
/*
* If we aren't blocking the Startup process there is
@@ -2819,6 +2831,8 @@ RecoveryConflictInterrupt(ProcSignalReason reason)
elog(FATAL, "Unknown conflict mode");
}
+ Assert(RecoveryConflictPending && (QueryCancelPending || ProcDiePending));
+
/*
* If it's safe to interrupt, and we're waiting for input or a lock,
* service the interrupt immediately