From 959ac58c04130d467fb05e63a3ceb8e2ded404c7 Mon Sep 17 00:00:00 2001 From: Simon Riggs Date: Sat, 23 Jan 2010 16:37:12 +0000 Subject: In HS, Startup process sets SIGALRM when waiting for buffer pin. If woken by alarm we send SIGUSR1 to all backends requesting that they check to see if they are blocking Startup process. If so, they throw ERROR/FATAL as for other conflict resolutions. Deadlock stop gap removed. max_standby_delay = -1 option removed to prevent deadlock. --- src/backend/storage/buffer/bufmgr.c | 40 +++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'src/backend/storage/buffer/bufmgr.c') diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 77f35fd361d..470800d5f47 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.254 2010/01/02 16:57:51 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.255 2010/01/23 16:37:12 sriggs Exp $ * *------------------------------------------------------------------------- */ @@ -44,6 +44,7 @@ #include "storage/ipc.h" #include "storage/proc.h" #include "storage/smgr.h" +#include "storage/standby.h" #include "utils/rel.h" #include "utils/resowner.h" @@ -2417,13 +2418,48 @@ LockBufferForCleanup(Buffer buffer) PinCountWaitBuf = bufHdr; UnlockBufHdr(bufHdr); LockBuffer(buffer, BUFFER_LOCK_UNLOCK); + /* Wait to be signaled by UnpinBuffer() */ - ProcWaitForSignal(); + if (InHotStandby) + { + /* Share the bufid that Startup process waits on */ + SetStartupBufferPinWaitBufId(buffer - 1); + /* Set alarm and then wait to be signaled by UnpinBuffer() */ + ResolveRecoveryConflictWithBufferPin(); + SetStartupBufferPinWaitBufId(-1); + } + else + ProcWaitForSignal(); + PinCountWaitBuf = NULL; /* Loop back and try again */ } } +/* + * Check called from RecoveryConflictInterrupt handler when Startup + * process requests cancelation of all pin holders that are blocking it. + */ +bool +HoldingBufferPinThatDelaysRecovery(void) +{ + int bufid = GetStartupBufferPinWaitBufId(); + + /* + * If we get woken slowly then it's possible that the Startup process + * was already woken by other backends before we got here. Also possible + * that we get here by multiple interrupts or interrupts at inappropriate + * times, so make sure we do nothing if the bufid is not set. + */ + if (bufid < 0) + return false; + + if (PrivateRefCount[bufid] > 0) + return true; + + return false; +} + /* * ConditionalLockBufferForCleanup - as above, but don't wait to get the lock * -- cgit v1.2.3