1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

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.
This commit is contained in:
Simon Riggs
2010-02-13 01:32:20 +00:00
parent fafa374f2d
commit b95a720a48
8 changed files with 86 additions and 26 deletions

View File

@ -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