diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/storage/ipc/standby.c | 23 | ||||
| -rw-r--r-- | src/backend/storage/lmgr/lock.c | 7 | ||||
| -rw-r--r-- | src/backend/storage/lmgr/proc.c | 9 | ||||
| -rw-r--r-- | src/include/storage/standby.h | 2 | 
4 files changed, 22 insertions, 19 deletions
| diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index ce02fe76049..e6b1fce61e6 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -463,24 +463,25 @@ SendRecoveryConflictWithBufferPin(ProcSignalReason reason)  /*   * In Hot Standby perform early deadlock detection.  We abort the lock - * wait if are about to sleep while holding the buffer pin that Startup - * process is waiting for. The deadlock occurs because we can only be - * waiting behind an AccessExclusiveLock, which can only clear when a - * transaction completion record is replayed, which can only occur when - * Startup process is not waiting. So if Startup process is waiting we - * never will clear that lock, so if we wait we cause deadlock. If we - * are the Startup process then no need to check for deadlocks. + * wait if we are about to sleep while holding the buffer pin that Startup + * process is waiting for. + * + * Note: this code is pessimistic, because there is no way for it to + * determine whether an actual deadlock condition is present: the lock we + * need to wait for might be unrelated to any held by the Startup process. + * Sooner or later, this mechanism should get ripped out in favor of somehow + * accounting for buffer locks in DeadLockCheck().  However, errors here + * seem to be very low-probability in practice, so for now it's not worth + * the trouble.   */  void -CheckRecoveryConflictDeadlock(LWLockId partitionLock) +CheckRecoveryConflictDeadlock(void)  { -	Assert(!InRecovery); +	Assert(!InRecovery);		/* do not call in Startup process */  	if (!HoldingBufferPinThatDelaysRecovery())  		return; -	LWLockRelease(partitionLock); -  	/*  	 * Error message should match ProcessInterrupts() but we avoid calling  	 * that because we aren't handling an interrupt at this point. Note that diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index f48193c8e73..73cfea2baa0 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -830,13 +830,6 @@ LockAcquireExtended(const LOCKTAG *locktag,  		}  		/* -		 * In Hot Standby perform early deadlock detection in normal backends. -		 * If deadlock found we release partition lock but do not return. -		 */ -		if (RecoveryInProgress() && !InRecovery) -			CheckRecoveryConflictDeadlock(partitionLock); - -		/*  		 * Set bitmask of locks this process already holds on this object.  		 */  		MyProc->heldLocks = proclock->holdMask; diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 2608fea9451..8896f6c2dbb 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -927,6 +927,15 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)  	 */  	LWLockRelease(partitionLock); +	/* +	 * Also, now that we will successfully clean up after an ereport, it's +	 * safe to check to see if there's a buffer pin deadlock against the +	 * Startup process.  Of course, that's only necessary if we're doing +	 * Hot Standby and are not the Startup process ourselves. +	 */ +	if (RecoveryInProgress() && !InRecovery) +		CheckRecoveryConflictDeadlock(); +  	/* Reset deadlock_state before enabling the signal handler */  	deadlock_state = DS_NOT_YET_CHECKED; diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h index 42fa0c04a17..2df838f40fc 100644 --- a/src/include/storage/standby.h +++ b/src/include/storage/standby.h @@ -35,7 +35,7 @@ extern void ResolveRecoveryConflictWithDatabase(Oid dbid);  extern void ResolveRecoveryConflictWithBufferPin(void);  extern void SendRecoveryConflictWithBufferPin(ProcSignalReason reason); -extern void CheckRecoveryConflictDeadlock(LWLockId partitionLock); +extern void CheckRecoveryConflictDeadlock(void);  /*   * Standby Rmgr (RM_STANDBY_ID) | 
